Spring 주해 프로 그래 밍 모델 지식 상세 설명
원 주 해 는 무엇 입 니까?
이른바 원 주해 란 주해 에 표 시 된 주해 이다.이런 방식 으로 형 성 된 주해 등급 구조 에서 원 주 해 는 등급 구조의 위 에 있 고 나 는 그의 아버지 주해(Super Annotation)라 고 부 르 며 주 해 된 주 해 는 등급 구조의 아래 에 있 고 서브 주해(Sub Annotation)라 고 부른다.원 주 해 를 도입 하 는 목적 은 속성 재 작성(Attribute Override)의 목적 을 실현 하기 위 한 것 이다.
간단 한 예 를 들다.
하나의 클래스 홈 과 두 개의 주석 이 있 습 니 다.하 나 는@Parent 이 고 다른 하 나 는@Child 입 니 다.@Parent 는@Child 에 표시 되 어 있 습 니 다.@Child 는 Home 에 표시 되 어 있 습 니 다.모두 하나의 속성 만 있 습 니 다.name 이 라 고 합 니 다[email protected] 의 기본 값 이'John'이 고@Child.name 의 기본 값 은'Jack'입 니 다.
이때 홈 에서@Child.name 을 가 져 오 면'Jack'으로 돌아 가 야 합 니 다.걱정 이 없습니다.
그렇다면@Parent.name 을 가 져 오 면 무엇 을 되 돌려 야 합 니까?Spring 주해 의'파생 성',@Child.name [email protected] 에 따 르 면 결 과 를 되 돌려 주 는 것 도'Jack'입 니 다.
상술 한 예 중의 클래스 와 주 해 는 코드 가 대체로 다음 과 같다.
@interface Parent {
String name() default "John";
}
@Parent
@interface Child {
String name() default "Jack";
}
@Child
class Home { }
주해 계층 구조:@Parent
@Child
'속성 재 작성'에 비해 또 다른 개념 은'속성 별명'(Alias)이 고 속성 별명 은 서로 등가 이다.
저 희 는 위의@Child 에 속성 value 를 추가 하고@AliasFor 를 사용 하여@Child.name 과@Child.value 를 서로 별명 으로 만 들 고 기본 값 은 빈 문자열 입 니 다.
@interface Child {
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
}
홈 에 표시 할 때@Child.value 에"Jack"값 을 설정 합 니 다.
@Child("Jack")
class Home { }
이 때@Child.name 을 가 져 오 든@Child.value 를 가 져 오 든 그 결 과 는 항상 같 습 니 다.모두"Jack"입 니 다.속성 별명 간 의 등가 성 을 설명 하 였 다.속성 별명 과 속성 재 작성
속성 별명 과 속성 재 작성 은 전혀 다른 개념 이지 만 구분 하지 않 고 개념 을 모호 하 게 하면 일부 현상 이 기대 에 부합 되 지 않 아 의외 라 고 느 낄 수 있다.다음 사례 를 고려 하여@A.a 1,@A.a 2,@B.a1,@B.b,@C.c,@C.b 의 값 을 제시 합 니 다.
@interface A {
String a1() default "1";
String a2() default "1";
}
@A
@interface B {
String a1() default "2";
@AliasFor(value = "a2", annotation = A.class)
String b() default "2";
}
@B
@interface C {
@AliasFor(value = "a1", annotation = B.class)
String c() default "3";
String b() default "3";
}
제 가 개념 을 파악 하지 못 하기 전에 답 은@A.a 1,@A.a 2,@B.a 1,@B.b,@C.c,@C.b 가 모두'3'이 라 고 생각 합 니 다.이 유 는 다음 과 같다.
왜 그런 지 에 대해 서 는 속성 별명 과 속성 을 진지 하 게 이해 하고 이 두 개념 을 다시 쓰 자.
공식 위 키 인용https://github.com/spring-projects/spring-framework/wiki/Spring-Annotation-Programming-Model그 중 에는 이 두 개념 에 대한 해명 이 있다.'Attribute Aliases and Overrides'1 절 에서 공식 원문 은 다음 과 같다.
An attribute alias is an alias from one annotation attribute to another annotation attribute. Attributes within a set of aliases can be used interchangeably and are treated as equivalent. Attribute aliases can be categorized as follows.
Explicit Aliases: if two attributes in one annotation are declared as aliases for each other via @AliasFor, they are explicit aliases.
Implicit Aliases: if two or more attributes in one annotation are declared as explicit overrides for the same attribute in a meta-annotation via @AliasFor, they are implicit aliases.
Transitive Implicit Aliases: given two or more attributes in one annotation that are declared as explicit overrides for attributes in meta-annotations via @AliasFor, if the attributes effectively override the same attribute in a meta-annotation following the law of transitivity, they are transitive implicit aliases.
An attribute override is an annotation attribute that overrides (or shadows) an annotation attribute in a meta-annotation. Attribute overrides can be categorized as follows.
Implicit Overrides: given attribute A in annotation @One and attribute A in annotation @Two, if @One is meta-annotated with @Two, then attribute A in annotation @One is an implicit override for attribute A in annotation @Two based solely on a naming convention (i.e., both attributes are named A).
Explicit Overrides: if attribute A is declared as an alias for attribute B in a meta-annotation via @AliasFor, then A is an explicit override for B.
Transitive Explicit Overrides: if attribute A in annotation @One is an explicit override for attribute B in annotation @Two and B is an explicit override for attribute C in annotation @Three, then A is a transitive explicit override for C following the law of transitivity.
속성 별명 은 세 가지 가 있 는데 각각 명시 적 별명,암시 적 별명 과 전달 암시 적 별명 이다.'속성 별명'은 같은 주석 내부 에서 만 발생 할 수 있다.예 를 들 면:
현식 별명(서로@AliasFor),@A.a 1 과@A.a 2,
@interface A {
@AliasFor("a2")
String a1() default "";
@AliasFor("a1")
String a2() default "";
}
암시 적 별명(@AliasFor 에서 같은 속성 으로),@B.b1 과@B.b2
@interface A {
String a() default "";
}
@A
@interface B {
@AliasFor(value = "a", annotation = A.class)
String b1() default "";
@AliasFor(value = "a", annotation = A.class)
String b2() default "";
}
암시 적 별명 전달(최종@AliasFor 에서 같은 속성 으로)@C.c1 과@C.c2
@interface A {
String a() default "";
}
@A
@interface B {
@AliasFor(value = "a", annotation = A.class)
String b() default "";
}
@B
@interface C {
@AliasFor(value = "a", annotation = A.class)
String c1() default "";
@AliasFor(value = "b", annotation = B.class)
String c2() default "";
}
속성 재 작성 도 세 가지 가 있 는데 그것 이 바로 암시 적 재 작성,명시 적 재 작성 과 전달 명시 적 재 작성 이다.'속성 재 작성'은 주석 사이 에서 만 발생 할 수 있다.예 를 들 면:암시 적 재 작성(동명 속성),@B.a 재 작성@A.a
@interface A {
String a() default "";
}
@A
@interface B {
String a() default "";
}
명시 적 재 작성(@AliasFor 필요),@B.b 재 작성@A.a
@interface A {
String a() default "";
}
@A
@interface B {
@AliasFor(value = "a", annotation = A.class)
String b() default "";
}
전달 현식 재 작성(@AliasFor 필요),@C.c 재 작성@B.b,@B.b 재 작성@A.a,그래서@C.c 도@A.a 를 재 작성 합 니 다.
@interface A {
String a() default "";
}
@A
@interface B {
@AliasFor(value = "a", annotation = A.class)
String b() default "";
}
@B
@interface C {
@AliasFor(value = "b", annotation = B.class)
String c() default "";
}
잘 이해 한 후에 우 리 는 아까 의 문제 로 돌아 가서 사례 를 다음 과 같이 다시 붙 였 다.
@interface A {
String a1() default "1";
String a2() default "1";
}
@A
@interface B {
String a1() default "2";
@AliasFor(value = "a2", annotation = A.class)
String b() default "2";
}
@B
@interface C {
@AliasFor(value = "a1", annotation = B.class)
String c() default "3";
String b() default "3";
}
해답 절 차 는:'명시 적 전달 재 작성'에 대해 서 는'@A.a 1 은@B.a1 에 의 해 암시 적 으로 재 작성 되 고@B.a1 은@C.c 에 의 해 명시 적 으로 재 작성 된다'거나'@A.a 2 는@B.b 에 의 해 명시 적 으로 재 작성 되 고 B.b 는@C.b 에 의 해 암시 적 으로 재 작성 된다'는 식 으로 재 작성 관 계 는 전달 되 지 않 습 니 다.
총결산
속성 별명 은 세 가지 가 있 는데 각각 명시 적 별명,암시 적 별명 과 전달 암시 적 별명 이다.'속성 별명'은 같은 주석 내부 에서 만 발생 할 수 있다.속성 재 작성 도 세 가지 가 있 는데 그것 이 바로 암시 적 재 작성,명시 적 재 작성 과 전달 명시 적 재 작성 이다.'속성 재 작성'은 주석 사이 에서 만 발생 할 수 있다.
후기
Spring 은 주해 프로 그래 밍 모델 의 코드 구현 에 있어 주로 Annotated Element Utils 와 같은 종류 에서 시험 을 할 때 이 방법 을 사용 할 수 있 습 니 다.
AnnotatedElementUtils#getMergedAnnotationAttributes。
주의해 야 할 것 은'암시 적 재 작성'은 value 속성 에 적용 되 지 않 습 니 다.value 속성 은 상대 적 으로 특수 한 속성 인 것 같 습 니 다.
다음 예제,@B.value 는 암시 적 으로@A.value 를 다시 쓰 지 않 습 니 다.
@interface A {
String value() default "a";
}
@A
@interface B {
String value() default "b";
}
그러나 속성 명 이 value 가 아니라면 암시 적 으로 다시 쓸 수 있 습 니 다[email protected] 암시 적 으로@A.xxx 를 다시 쓸 수 있 습 니 다.
@interface A {
String xxx() default "a";
}
@A
@interface B {
String xxx() default "b";
}
나 는 다음 과 같은 소스 코드 를 따라 갔다.소스 코드 에서 value 속성 에 대해 특별한 판단 을 한 것 을 발견 했다.코드 위 치 는 org.springframework.core.annotation.annotation.annotated Element Utils.Merged Annotation Attributes Processor\#postprocess 방법 에서 코드 세 션 은 다음 과 같다.
// Implicit annotation attribute override based on convention
else if (!AnnotationUtils.VALUE.equals(attributeName) && attributes.containsKey(attributeName)) {
overrideAttribute(element, annotation, attributes, attributeName, attributeName);
}
그 중에서 AnnotationUtils.VALUE 는 상수 이 고 그 값 은'value'이다.value 속성 을 왜 특수 처리 해 야 하 는 지 공식 적 으로 설명 하지 못 했 습 니 다.많은 주석 이 하나의 속성 만 있 을 것 이 라 고 추측 합 니 다.프로 그래 밍 이 편리 하기 위해 서 는@A(value="hello World)가 필요 없 기 때문에@A("hello World")만 사용 하면 됩 니 다.이 경우 암시 적 으로 다시 쓰 면 인 코딩 자가 원 하 는 결과 가 아 닐 수 있 습 니 다.특히 명시 적 재 작성 은 이러한 특별한 처리 가 없 으 며,아래 예제@B.value 는 명시 적 으로@A.value 를 다시 씁 니 다.
@interface A {
String value() default "a";
}
@A
@interface B {
@AliasFor(annotation = A.class)
String value() default "b";
}
본 논문 에서 다 루 는 Spring Boot 버 전>=2.0.2.RELEASE.이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
thymeleaf로 HTML 페이지를 동적으로 만듭니다 (spring + gradle)지난번에는 에서 화면에 HTML을 표시했습니다. 이번에는 화면을 동적으로 움직여보고 싶기 때문에 입력한 문자를 화면에 표시시키고 싶습니다. 초보자의 비망록이므로 이상한 점 등 있으면 지적 받을 수 있으면 기쁩니다! ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.