클라이언트의 요청을 대신 받는 대리인 역할
실제 오브젝트인 타겟은 프로젝트를 통해 요청을 받아 처리함
타겟은 자신의 기능에만 집중하고, 부가기능은 프록시에게 위임한다.
위의 단점을 동적 프록시를 통해 해결할 수 있다.
스프링에서는 ProxyFactoryBean에서 인터페이스 유무를 확인하여 인터페이스가 있으면 JDK Dynamic Proxy를 쓰도록 하고 없으면 CGLIB를 쓰도록 결정한다.
@RequestBody를 통해 JSON 응답에 대한 역직렬화 시 기본 생성자가 필요하다고 알고있었다. @Builder은 기본 생성자를 만들지 않기 때문에 정상 동작하지 않을거라고 예상했었다.
하지만 아래와 같이 @Builder가 붙어도 Dto 클래스의 역직렬화는 문제 없이 동작 했었다.
@Builder
@Getter
public class MemberRequestDto {
@Pattern(regexp = RegexUtils.MEMBER_ID_REGEX, message = "id형식에 맞지 않습니다.")
private String id;
@Pattern(regexp = RegexUtils.PWD_REGEX, message = "비밀번호 형식에 맞지 않습니다.")
private String password;
@Pattern(regexp = RegexUtils.USER_NAME_REGEX, message = "사용자 이름 형식에 맞지 않습니다.")
private String userName;
@Pattern(regexp = RegexUtils.EMAIL_REGEX, message = "이메일 형식에 맞지 않습니다.")
private String email;
}
@Builder, @Getter로 생성된 코드(.class파일에서 확인)
@Builder를 통해 모든 필드를 가진 생성자가 만들어졌습니다.
MemberRequestDto(final String id, final String password, final String userName, final String email) {
this.id = id;
this.password = password;
this.userName = userName;
this.email = email;
}
public static MemberRequestDtoBuilder builder() {
return new MemberRequestDtoBuilder();
}
public String getId() {
return this.id;
}
public String getPassword() {
return this.password;
}
public String getUserName() {
return this.userName;
}
public String getEmail() {
return this.email;
}
위의 코드로 작성 후 디버깅 하면 BeanDeserializer클래스의 deserialize메소드에 걸리게 된다.
deserialize 메소드가 리턴하는 deserializeFromObject을 확인해보자
기본 생성자가 있을때는 _nonStandardCreation = false여서 if 문을 타지 않는데, 기본생성자가 없을 경우 아래 조건문을 타게 된다.
_nonStandardCreation 필드는 역직렬화 시 객체가 표준적인 방식(기본 생성자)으로 바인딩 하지 않은 경우 사용되는 flag라고 한다.
if (_nonStandardCreation)에 만족하게 되면 기본생성자가 없는 경우는 deserializeFromObjectUsingNonDefault(메소드 이름에서부터 알 수 있다.)를 타게 되고, 기본 생성자가 있는 경우 조건문을 타지 않고 아래 메소드(_valueInstantiator.createUsingDefault(ctxt);)를 타게 된다.
deserializeFromObjectUsingNonDefault 내부에서는 delegateDeser와 메소드와 PropertyBasedCreator타입의 _propertyBasedCreator 검사 조건식으로 나뉜다.
delegateDeser대리자를 통한 역직렬화 방식 체크 ( 대리자가 뭘 뜻하는지 아직 모르겠다.)Deserializer that is used iff delegate-based creator is to be used for deserializing from JSON Object.
NOTE: cannot be final because we need to get it during resolve() method (and not contextualization).
_propertyBasedCreator프로퍼티 기반(필드명을 비교한 방식) 역직렬화 방식 체크If the bean needs to be instantiated using constructor or factory method that takes one or more named properties as argument(s), this creator is used for instantiation. This value gets resolved during general resolution.
_deserializeUsingPropertyBased 의 역할은 프로퍼티(필드 이름을 기반하여)를 사용하여 객체 역직렬화 하는 메소드이다.
해당 메소드를 통해 propName에 필드값과, value필드에 값이 셋팅 된다.
propName과 value를 통해 역직렬화 된 Object를 리턴하고있다.
❗마무리
[참고]