<context:annotation-config>
응용 프로그램 컨텍스트에 이미 등록 된 Bean에서 주석을 활성화하는 데 사용됩니다 (XML 또는 패키지 스캔으로 정의 된 경우에 상관없이).
<context:component-scan>
또한 무엇을 할 수 <context:annotation-config>
않고 <context:component-scan>
애플리케이션 컨텍스트 내에서 콩을 찾아 등록 패키지를 스캔도.
차이점 / 유사성을 보여주기 위해 몇 가지 예를 사용하겠습니다.
세 종류의 콩의 기본 설정으로 시작하자 A
, B
과 C
함께 B
그리고 C
주입되는 A
.
package com.xxx;
public class B {
public B() {
System.out.println("creating bean B: " + this);
}
}
package com.xxx;
public class C {
public C() {
System.out.println("creating bean C: " + this);
}
}
package com.yyy;
import com.xxx.B;
import com.xxx.C;
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
다음과 같은 XML 구성을 사용하십시오.
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A">
<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />
</bean>
컨텍스트를로드하면 다음과 같은 출력이 생성됩니다.
creating bean B: com.xxx.B@c2ff5
creating bean C: com.xxx.C@1e8a1f6
creating bean A: com.yyy.A@1e152c5
setting A.bbb with com.xxx.B@c2ff5
setting A.ccc with com.xxx.C@1e8a1f6
이것은 예상 된 결과입니다. 그러나 이것은 "오래된 스타일"봄입니다. 이제 주석이 있으므로 주석을 사용하여 XML을 단순화 할 수 있습니다.
먼저 다음 bbb
과 같이 ccc
bean 에서 and 속성을 자동 와이어 링합니다 A
.
package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import com.xxx.B;
import com.xxx.C;
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
@Autowired
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
@Autowired
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
이를 통해 XML에서 다음 행을 제거 할 수 있습니다.
<property name="bbb" ref="bBean" />
<property name="ccc" ref="cBean" />
내 XML은 이제 다음과 같이 단순화되었습니다.
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />
컨텍스트를로드하면 다음과 같은 결과가 나타납니다.
creating bean B: com.xxx.B@5e5a50
creating bean C: com.xxx.C@54a328
creating bean A: com.yyy.A@a3d4cf
좋아, 이건 잘못이야! 어떻게 된 거예요? 왜 내 속성이 자동으로 연결되지 않습니까?
주석은 좋은 기능이지만 그 자체로는 아무것도하지 않습니다. 그들은 단지 주석을 달았습니다. 주석을 찾아서 처리하려면 처리 도구가 필요합니다.
<context:annotation-config>
구조에. 이는 자체 정의 된 동일한 애플리케이션 컨텍스트에 정의 된 Bean에서 찾은 주석에 대한 조치를 활성화합니다.
XML을 다음과 같이 변경하면
<context:annotation-config />
<bean id="bBean" class="com.xxx.B" />
<bean id="cBean" class="com.xxx.C" />
<bean id="aBean" class="com.yyy.A" />
응용 프로그램 컨텍스트를로드하면 올바른 결과가 나타납니다.
creating bean B: com.xxx.B@15663a2
creating bean C: com.xxx.C@cd5f8b
creating bean A: com.yyy.A@157aa53
setting A.bbb with com.xxx.B@15663a2
setting A.ccc with com.xxx.C@cd5f8b
좋아, 이것은 훌륭하지만 XML에서 두 개의 행을 제거하고 하나를 추가했습니다. 큰 차이는 아닙니다. 주석이있는 아이디어는 XML을 제거해야한다는 것입니다.
XML 정의를 제거하고 주석으로 모두 바꾸자.
package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class B {
public B() {
System.out.println("creating bean B: " + this);
}
}
package com.xxx;
import org.springframework.stereotype.Component;
@Component
public class C {
public C() {
System.out.println("creating bean C: " + this);
}
}
package com.yyy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.xxx.B;
import com.xxx.C;
@Component
public class A {
private B bbb;
private C ccc;
public A() {
System.out.println("creating bean A: " + this);
}
@Autowired
public void setBbb(B bbb) {
System.out.println("setting A.bbb with " + bbb);
this.bbb = bbb;
}
@Autowired
public void setCcc(C ccc) {
System.out.println("setting A.ccc with " + ccc);
this.ccc = ccc;
}
}
XML에서 우리는 이것을 유지합니다.
<context:annotation-config />
컨텍스트를로드하면 결과는 ... Nothing입니다. Bean이 작성되지 않고 Bean이 자동 연결되지 않습니다. 아무것도!
첫 번째 단락에서 말했듯 <context:annotation-config />
이 응용 프로그램 컨텍스트에 등록 된 Bean에서만 작동 하기 때문 입니다. 세 개의 Bean에 대한 XML 구성을 제거했기 때문에 작성된 Bean <context:annotation-config />
이없고 작업 할 "대상"이 없습니다.
그러나 <context:component-scan>
"대상"이 작동하도록 패키지를 스캔 할 수 있는 문제는 아닙니다 . XML 구성의 내용을 다음 항목으로 변경하십시오.
<context:component-scan base-package="com.xxx" />
컨텍스트를로드하면 다음과 같은 결과가 나타납니다.
creating bean B: com.xxx.B@1be0f0a
creating bean C: com.xxx.C@80d1ff
흠 ... 뭔가 빠졌습니다. 왜?
당신이 클래스에 closelly 보면, 클래스는 A
패키지를 가지고 com.yyy
하지만 난에서 지정한 <context:component-scan>
패키지를 사용하는 com.xxx
이 완전히 내 놓친 있도록 A
클래스를 만 포착 B
하고 C
어느에있는 com.xxx
패키지.
이 문제를 해결하기 위해 다른 패키지도 추가합니다.
<context:component-scan base-package="com.xxx,com.yyy" />
이제 예상 결과를 얻습니다.
creating bean B: com.xxx.B@cd5f8b
creating bean C: com.xxx.C@15ac3c9
creating bean A: com.yyy.A@ec4a87
setting A.bbb with com.xxx.B@cd5f8b
setting A.ccc with com.xxx.C@15ac3c9
그리고 그게 다야! 이제 더 이상 XML 정의가 없으며 주석이 있습니다.
최종 예를 들어, 주석 클래스를 유지 A
, B
그리고 C
우리는 컨텍스트를로드 한 후 무엇을 얻을 것이다, 그리고 XML에 다음을 추가?
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
우리는 여전히 올바른 결과를 얻습니다.
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
클래스의 Bean을 A
스캔하여 확보하지 않더라도 처리 도구는 여전히 <context:component-scan>
애플리케이션 컨텍스트에 등록 된 모든 Bean에 적용되며 A
, XML에 수동으로 등록 된 경우 에도 마찬가지입니다 .
그러나 만약 우리가 다음과 같은 XML을 가지고 있다면, <context:annotation-config />
그리고 둘 다 지정했기 때문에 중복 된 bean을 얻게 <context:component-scan>
될까요?
<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
아니요, 중복이 없습니다. 다시 예상 결과를 얻습니다.
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@1d64c37
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
두 태그가 동일한 처리 도구를 지정하기 때문입니다 (지정된 <context:annotation-config />
경우 생략 가능 <context:component-scan>
). 그러나 Spring은 한 번만 실행을 처리합니다.
처리 도구를 여러 번 직접 등록하더라도 Spring은 여전히 한 번만 마법을 수행하도록합니다. 이 XML :
<context:annotation-config />
<context:component-scan base-package="com.xxx" />
<bean id="aBean" class="com.yyy.A" />
<bean id="bla" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla1" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla2" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean id="bla3" class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
여전히 다음과 같은 결과가 생성됩니다.
creating bean B: com.xxx.B@157aa53
creating bean C: com.xxx.C@ec4a87
creating bean A: com.yyy.A@25d2b2
setting A.bbb with com.xxx.B@157aa53
setting A.ccc with com.xxx.C@ec4a87
좋아, 랩은 끝이야.
@Tomasz Nurkiewicz와 @Sean Patrick Floyd의 답변과 함께이 정보가 방법 <context:annotation-config>
과 <context:component-scan>
작업 을 이해하는 데 필요한 모든 것이기를 바랍니다
.