머리말
이 기사는 주로 봄의 조회 (메소드 주입)에 관한 관련 내용을 소개합니다. 참조와 학습을 위해 공유됩니다. 나는 아래에서 많이 말하지 않을 것입니다. 자세한 소개를 함께 살펴 보겠습니다.
스프링을 사용할 때 발생할 수 있습니다. 하나의 싱글 톤 콩은 다른 비 싱턴 콩에 따라 다릅니다. 자가 조립을 사용하여 종속성을 주입하는 경우 다음과 같이 일부 문제가 발생할 수 있습니다.
싱글 톤의 클래스 A
@componentpublic class classa {@autowired private classb; public void printclass () {system.out.println ( "이것은 클래스 A :" + this); classb.printclass (); }}비 단일에 대한 클래스 B
@component@scope (value = scope_prototype) public class classb {public void printclass () {System.out.println ( "이것은 클래스 B :" + this); }} 여기에서 클래스 A는 기본 싱글 톤 범위를 채택하고 클래스 B에 의존합니다. 클래스 B의 범위는 프로토 타입이므로 싱글 톤이 아닙니다. 현재 테스트를 실행 한 후 다음과 같은 글쓰기 문제를 볼 수 있습니다.
@runwith (springrunner.class) @contextConfiguration (class = {classa.class, classb.class}) public class mytest {@autowired private classa classa; @test public void simpletest () {for (int i = 0; i <3; i ++) {classa.printclass (); }}}출력 결과는 다음과 같습니다.
클래스 A : Classa@282003E1입니다
이것은 클래스 B : classb@7fad8c79입니다
클래스 A : Classa@282003E1입니다
이것은 클래스 B : classb@7fad8c79입니다
클래스 A : Classa@282003E1입니다
이것은 클래스 B : classb@7fad8c79입니다
보시다시피, 두 클래스의 해시 코드는 세 가지 출력에서 동일합니다. 클래스 A의 가치는 싱글 톤이기 때문에 클래스 A의 가치가 변경되지 않지만 클래스 B의 범위는 프로토 타입이지만 해시 코드를 변경하지 않은 것으로 보이며 싱글 톤이 된 것 같습니다.
이 상황의 이유는 클래스 A의 범위가 기본 싱글 톤이기 때문에 컨텍스트는 클래스 A의 Bean 만 한 번만 생성하므로 종속성을 주입 할 기회는 단 하나 뿐이며 컨테이너는 매번 새로운 클래스 B를 클래스 A를 제공 할 수 없습니다.
그렇게 좋은 해결책이 아닙니다
위의 문제를 해결하려면 ApplicationContextAware를 구현하기 위해 클래스 A를 수정할 수 있습니다.
@ComponentPublic Classa Classa는 ApplicationContextAware {private applicationContext ApplicationContext를 구현합니다. public void printclass () {system.out.println ( "이것은 클래스 A :" + this); getClassB (). printClass (); } public classb getClassb () {return applicationcontext.getBean (classb.class); } public void setApplicationContext (ApplicationContext ApplicationContext)는 beansexception {this.applicationContext = ApplicationContext; }}이렇게하면 클래스 B로 갈 때마다 컨텍스트에서 새 콩을 수동으로 찾을 수 있습니다. 다른 테스트를 실행 한 후 다음 출력을 얻었습니다.
클래스 A : com.devhao.classa@4df828d7입니다
클래스 B : com.devhao.classb@31206beb입니다
클래스 A : com.devhao.classa@4df828d7입니다
클래스 B : com.devhao.classb@3e77a1ed입니다
클래스 A : com.devhao.classa@4df828d7입니다
클래스 B : com.devhao.classb@3ffcd140입니다
클래스 A의 해시 코드는 세 가지 출력에서 변경되지 않은 상태로 유지되는 반면 클래스 B는 매번 다릅니다. 이는 문제가 해결되었고 새 인스턴스가 호출 될 때마다 사용됨을 보여줍니다.
그러나이 작문 방법은 봄과 밀접하게 결합되며 Spring은 침습성을 줄이는 또 다른 방법을 제공합니다.
@Lookup
Spring은 @Lookup이라는 주석을 제공합니다. @Lookup은 메소드에 작동하는 주석입니다. 그로 표시된 메소드는 재정의됩니다. 그런 다음 리턴 값의 유형에 따라 컨테이너는 콩의 getBean () 메소드를 호출하여 콩을 반환합니다.
@componentpublic classa classa {public void printclass () {system.out.println ( "이것은 클래스 A :" + this); getClassB (). printClass (); } @lookup public classb getClassb () {return null; }} 훨씬 단순하고 더 이상 스프링과 밀접하게 결합되지 않는다는 것을 알 수 있습니다. 테스트를 다시 실행하면 여전히 올바른 출력이 발생할 수 있습니다.
컨테이너가 서브 클래스를 동적으로 생성 한 다음 주석이 달린 메소드를 다시 작성/구현하고 하위 클래스 메소드가 호출되기 때문에 주석이 달린 방법의 반환 값이 더 이상 중요하지 않습니다.
사용 된 @Lookup 방법은 다음 서명을 준수해야합니다.
<public | protected> [Abstract] <Return-type> themEthodName (Arguments);
요약
위는이 기사의 전체 내용입니다. 이 기사의 내용에 모든 사람의 연구 나 작업에 대한 특정 참조 가치가 있기를 바랍니다. 궁금한 점이 있으면 의사 소통을 위해 메시지를 남길 수 있습니다. Wulin.com을 지원 해주셔서 감사합니다.