인프런 커뮤니티 질문&답변

세승님의 프로필 이미지
세승

작성한 질문수

스프링 MVC 2편 - 백엔드 웹 개발 활용 기술

뷰 템플릿에 컨버터 적용하기

IpPort 객체가 동일한 이유?

해결된 질문

작성

·

517

0

안녕하세요. 강의를 듣던중 궁금한점이 생겨 질문 드립니다.

아래는 뷰 템플릿에 컨버터를 적용하는 강의에서 컨트롤러에서 사용되는 두개의 함수입니다.

    @GetMapping("/converter/edit")
    public String conveterForm(Model model) {
        IpPort ipPort = new IpPort("127.0.0.1", 8080);
        System.out.println(ipPort);
        Form form = new Form(ipPort);

        model.addAttribute("form", form);
        return "converter-form";

    }

    @PostMapping("/converter/edit")
    public String conveterEdit(@ModelAttribute Form form, Model model) {
        IpPort ipPort = form.getIpPort();
        model.addAttribute("ipPort", ipPort);
        return "converter-view";

    }

위와 같은 코드에서 위의 GET mapping을 호출하면,

스크린샷 2023-02-27 오후 3.18.22.png다음과 같은 창이 나오는데요, 저 때, th:value의 레퍼런스 정보는 'hello.typeconverter.type.IpPort@59cb0946' 입니다.

그런데, 동일한 mapping(http://localhost:8080/converter/edit) 을 호출하면 매번 IpPort ipPort = new IpPort("127.0.0.1", 8080);에 의해 새로운 IpPort 객체가 생성되어야한다고 생각했었는데, 계속 같은 'hello.typeconverter.type.IpPort@59cb0946' 레퍼런스가 나옵니다.

또, 위의 페이지에서 submit을 할 경우에, "ipPort=127.0.0.1:8080" 이라는 값이 서버로 전달되어서, 컨버터에 의해 변환되어 @ModelAttribute Form form 안의 IpPort로 바인딩이 되는 것인데, 해당 페이지에도 아래와 같이 동일한 레퍼런스가 나타납니다.

스크린샷 2023-02-27 오후 3.23.33.pngGET localhost:8080/converter/edit

POST localhost:8080/converter/edit 는 독립적인 서로 다른 http 요청이라서 스프링 내부적으로 Form 객체 안의 IpPort객체를 바인딩하는 과정에서 새로운 IpPort 객체를 만들어서 바인딩 해줄 것이라고 생각했는데, 동일한 레퍼런스가 출력되었습니다.

이는 자바(JVM) 자체적으로 메모리를 관리하는 부분에 의한 영향인가요? 아니면 스프링 내부적으로 객체 레퍼런스를 재사용하는 매커니즘이 있는 건가요?

 

 

답변 1

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. 세승님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

 

세승님의 프로필 이미지
세승
질문자

위의 이유를 발견했습니다.

롬복 애너테이션으로 설정했던 @EqualsAndHashCode 때문이었네요.

해당 애너테이션으로 인해서, 객체 내부의 값(실제 객체의 참조주소가 아닌, 객체를 구성하는 필드들의 값)이 동일하면, 동일한 해시코드를 출력하게 되고, 그로 인해서 동일한 객체 레퍼런스가 출력되었던 것으로 확인하였습니다.

테스트코드에서 Assertions.assertThat().isEqualTo() 를 사용하여 두 객체의 같음을 비교할 때, 내부적으로 두 객체의 해시코드를 비교하여 같은지 여부를 판단하는 것 같습니다. 그래서, @EqualsAndHashCode를 특정 클래스에 추가하면, 해당 클래스의 인스턴스들은 객체를 구성하고 있는 내부 필드의 값들이 동일하면, 동일한 해시코드를 출력하게되고, 그러므로, 127.0.0.1:8080 이라는 동일한 주소를 갖는 IpPort 객체는 새롭게 생겨난 객체도 같은 해시코드를 갖게 되는 것이었습니다.

세승님의 프로필 이미지
세승

작성한 질문수

질문하기