편집 : Jackson의 관리자가 작성한 블로그 게시물 에서 2.12는 생성자 주입과 관련하여 개선 사항을 볼 수 있습니다. (이 편집 당시의 현재 버전은 2.11.1입니다.)
모호한 1- 인수 생성자 (위임 대 속성)로 문제 해결 / 완화를 포함하여 생성자 생성자의 자동 감지 기능을 개선합니다.
이것은 Jackson databind 2.7.0의 경우에도 마찬가지입니다.
잭슨 @JsonCreator
주석 2.5의 javadoc 이나 잭슨 주석 문서의 문법 ( 생성자 의 공장 방법 의 ) 사람이 할 수있는 참으로 믿게 표시 여러 생성자를.
생성자 및 팩토리 메서드를 연결된 클래스의 새 인스턴스를 인스턴스화하는 데 사용할 하나로 정의하는 데 사용할 수있는 마커 주석입니다.
생성자 가 식별 되는 코드를 보면 Jackson CreatorCollector
이 생성자 의 첫 번째 인수 만 확인 하기 때문에 오버로드 된 생성자를 무시 하는 것처럼 보입니다 .
Class<?> oldType = oldOne.getRawParameterType(0);
Class<?> newType = newOne.getRawParameterType(0);
if (oldType == newType) {
throw new IllegalArgumentException("Conflicting "+TYPE_DESCS[typeIndex]
+" creators: already had explicitly marked "+oldOne+", encountered "+newOne);
}
oldOne
처음으로 확인 된 생성자 생성자입니다.
newOne
오버로드 된 생성자 생성자입니다.
즉, 그런 코드 가 작동하지 않습니다.
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
this.country = "";
}
@JsonCreator
public Phone(@JsonProperty("country") String country, @JsonProperty("value") String value) {
this.value = value;
this.country = country;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
그러나이 코드는 작동합니다.
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
이것은 약간 엉망이고 미래의 증거가 아닐 수도 있습니다 .
문서는 객체 생성 작동 방식에 대해 모호합니다. 하지만 코드에서 수집 한 내용에서 다른 방법을 혼합 할 수 있다는 것입니다.
예를 들어 다음과 같이 주석이 달린 정적 팩토리 메소드를 가질 수 있습니다. @JsonCreator
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
enabled = true;
}
@JsonCreator
public Phone(@JsonProperty("enabled") Boolean enabled, @JsonProperty("value") String value) {
this.value = value;
this.enabled = enabled;
}
@JsonCreator
public static Phone toPhone(String value) {
return new Phone(value);
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
작동하지만 이상적이지 않습니다. 결국 그것은 의미가있을 수 있습니다. 예를 들어 json이 동적 인 경우에는 여러 주석 생성자보다 훨씬 더 우아하게 페이로드 변형을 처리하기 위해 위임 생성자를 사용해야합니다.
또한 Jackson 은 다음 코드와 같이 우선 순위에 따라 제작자를 주문 합니다.
@JsonCreator
public Phone(@JsonProperty("value") String value) {
this.value = value;
}
@JsonCreator
public Phone(Map<String, Object> properties) {
value = (String) properties.get("value");
}
assertThat(new ObjectMapper().readValue("\"+336\"", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\"}", Phone.class).value).isEqualTo("+336");
assertThat(new ObjectMapper().readValue("{\"value\":\"+336\",\"enabled\":true}", Phone.class).value).isEqualTo("+336");
이 시간 잭슨은 오류가 발생하지 않지만 잭슨에만 사용 위임 생성자 Phone(Map<String, Object> properties)
는 그 수단 Phone(@JsonProperty("value") String value)
사용되지 않습니다를.