소개 : 원형 의존성은 N 클래스의 루프 중첩 참조입니다. 이 원형 의존성이 새로운 객체 방법을 사용하여 일일 개발에서 발생하는 경우, 프로그램은 메모리가 오류가 넘치고 오류를보고 할 때까지 런타임에 루프를 계속 호출합니다. 원형 의존성을 해결하면 봄에 대해 이야기합시다.
첫 번째 유형 : 생성자 매개 변수 순환 종속성
스프링 컨테이너는 "현재 콩 풀"에 생성되는 각 Bean 식별자를 배치하고 생성 과정에서 Bean 식별자 가이 풀에 남아 있습니다. 따라서, 당신이 창조 과정에서 이미 "현재 콩 풀"에 있다는 것을 알게되면, 그것은 던져 질 것입니다.
BeanCurrentyInceceationException 예외는 원형 의존성을 나타냅니다. 생성 된 콩은 "현재 생성 된 콩 수영장"에서 지워집니다.
먼저 3 개의 콩을 초기화합니다.
공개 클래스 학생 {사립 학생 B 학생; public void setstudentb (wiching studentb) {this.studentb = windentb; } public studenta () {} public studenta (studentb 학생들) {this.studentb = studentb; }} 공개 클래스 학생 B {사생활 학생 C 학생; public void setstudentc (windentc elidentc) {this.studentc = windentc; } public studentb () {} public studentb (windentc elidentc) {this.studentc = studentc; }} 공개 클래스 학생 {사립 학생 학생; 공개 void setStudenta (Studenta Studenta) {this.studenta = studenta; } public studentc () {} public studentc (studenta studenta) {this.studenta = studenta; }}좋아요, 위는 세 가지 매우 기본적인 클래스입니다. Studenta 매개 변수 구조는 StudentB입니다. StudentB의 매개 변수 구조는 StudentC이고 StudentC의 매개 변수 구조는 학생이며 순환 의존성 상황을 만듭니다.
우리는 모두이 세 콩을 스프링 관리에 건네주고 매개 변수 구성으로 인스턴스화했습니다.
<bean id = "a"> <constructor-arg index = "0"ref = "b"> </constructor-arg> </bean> <bean id = "b"> <constructor-arg index = "0"ref = "c"> </constructor-arg> </bean> <bean id = "c"> </ban>> </bean> "a"</orguctor-ar-arg>
테스트 클래스는 다음과 같습니다.
공개 클래스 테스트 {public static void main (String [] args) {ApplicationContext context = new ClassPathXmlApplicationContext ( "com/zfx/withy/applicationcontext.xml"); //system.out.println(context.getbean("a ", studenta.class)); }}실행 결과의 오류 메시지는 다음과 같습니다.
원인 : org.springframework.beans.fackory.beancurrentyincreationException :
이름 'A'로 Bean을 생성하는 오류 : 요청 된 Bean은 현재 생성 중입니다. 해결할 수없는 원형 기준이 있습니까?
처음에 문장을 이해한다면이 오류를보고하는 것이 놀라지 않아야합니다. 스프링 컨테이너는 먼저 싱글 톤 학생을 만듭니다. Studenta는 StudentB에 의존하고 "현재 콩 수영장"에 A를 넣습니다. 현재 학생은 만들어지고 StudentB는 StudentC에 의존하고 B는 "현재 콩 수영장"에 배치됩니다. 현재 학생이 만들어지고 Studentc는 Studenta에 의존합니다. 그러나 현재 학생은 이미 수영장에 있으므로 오류 가보고됩니다. 수영장의 모든 콩이 초기화되지 않았으므로 오류에 따라 다릅니다. (초기화 된 콩은 수영장에서 제거됩니다)
두 번째 유형 : Setter Method Singleton, 기본 메소드
세터 주입에 대해 이야기하고 싶다면 봄에 콩을 인스턴스화하는 사진을 더 잘 보게 될 것입니다.
그림의 처음 두 단계에서 볼 수 있듯이 스프링은 Bean 객체를 인스턴스화 한 다음 객체 속성을 설정합니다.
구성 파일을 수정하여 설정 모드로 주입합니다.
<!-"싱글 톤"(기본값은 싱글 톤 메소드입니다)-> <bean id = "a"scope = "singleton"> <property name = "studentb"ref = "b"> </property> </bean> <bean id = "b"scope = "singleton"> <property name = "studentc"ref = "c"> name = "studenta"ref = "a"> </property> </bean>
테스트 클래스는 다음과 같습니다.
공개 클래스 테스트 {public static void main (String [] args) {ApplicationContext context = new ClassPathXmlApplicationContext ( "com/zfx/withy/applicationcontext.xml"); System.out.println (context.getBean ( "a", windenta.class)); }}인쇄 결과는 다음과 같습니다.
com.zfx.student.studenta@1fbfd6
설정 방법을 사용하여 실수를보고하지 않는 이유는 무엇입니까?
위의 그림을 봅시다. 스프링 먼저 구조물을 사용하여 Bean 물체를 인스턴스화합니다. 이 시점에서 Spring은 인스턴스형 객체를 맵에 넣고 Spring은 Unset 속성으로 인스턴스화 된 객체 참조를 얻는 방법을 제공합니다. 이 예를 바탕으로 Spring이 Studenta, Studentb 및 Studentc를 인스턴스화하면 객체 속성을 설정합니다. 현재 학생은 StudentB에 의존하여지도에서 Singleton StudentB 객체를 꺼낼 것입니다. 그러면 루프 문제가 없습니다.
다음은 스프링 소스 코드의 구현 방법입니다. 다음 소스 코드는 기본값 Spring 's Bean 패키지의 Java 클래스에 있습니다.
/ ** 싱글 톤 객체의 캐시 : bean 이름 -> bean 인스턴스 (싱글 톤 인스턴스화 객체를 캐시하는 맵 컬렉션)*/ 개인 최종 맵 <문자열, 객체> 싱글토 노브 jest = new consurenthashMap <string, object> (64); / ** 싱글 톤 공장의 캐시 : Bean Name-> ObjectFactory (Singleton Factory Bean 캐시 컬렉션)*/ 개인 최종지도 <문자열, ObjectFactory> SingletOnfactory = new Hashmap <String, ObjectFactory> (16); / ** 초기 싱글 톤 객체의 캐시 : bean 이름 -> bean 인스턴스*/ 개인 최종 맵 <문자열, 개체> 초기 싱으로 곤충 <new Hashmap <String, Object> (16); / ** 등록 명령에 Bean 이름을 포함하는 등록 된 싱글 톤 세트*/ 개인 최종 세트 <string> registeredsingletons = new LinkedHashset <string> (64); /*** 싱글 톤 인스턴스 추가* 원형 참조 문제 해결* 필요한 경우 지정된 싱글 톤을 구축하기 위해 주어진 싱글 톤 공장을 추가하십시오. * <p> 싱글 톤의 열렬한 등록을 요구하는 것, 예를 들어 원형 참조를 해결할 수 있도록 * <p>. * @param beaname Bean의 이름 * @param singletonfactory 싱글 톤 객체에 대한 공장 */ 보호 된 void addsingletonfactory (String beanname, objectfactory singletonfactory) {assert.notnull (SingletonFactory, "Singleton Factory가 unull이되어서는 안됩니다"); 동기화 (this.singletonObjects) {if (! this.singletonObjects.containskey (beanname)) {this.singletonfactories.put (beanname, singletonfactory); this.earlysingletonobjects.remove (beanname); this.registeredsingletons.add (beanname); }}세 번째 유형 : 세터 프로토 타입, 프로토 타입
구성 파일을 다음과 같이 수정하십시오.
<bean id = "a"<span style = "color :#ff0000;"> scope = "프로토 타입"</span >> <property name = "studentb"ref = "b"> </property> </bean> <bean id = "b"<span style = "color :#ff0000;"> "prototype"</span >> <in studentc "c"> id = "c"<span style = "color :#ff0000;"> scope = "프로토 타입"</span "<property name ="studentc "ref ="c "> </property> </bean> <bean id ="c "<span style ="color :#ff0000; "> scope ="prototype "<property name ="studenta "ref ="</property> </bean>
SCOPE = "프로토 타입"은 요청할 때마다 인스턴스 객체가 생성되었음을 의미합니다. 이 둘의 차이점은 다음과 같습니다. 상태가 많은 콩은 프로토 타입 범위를 사용하는 반면, 스테이틀리스는 일반적으로 싱글 톤 싱글 톤 범위를 사용합니다.
테스트 사례 :
공개 클래스 테스트 {public static void main (String [] args) {ApplicationContext context = new ClassPathXmlApplicationContext ( "com/zfx/withy/applicationcontext.xml"); <strong> // 현재 스프링 인스턴스를 관리해야합니다. 이제 scope = "프로토 타입"은 </strong> system.out.println (context.getbean ( "a", winderea.class))을 요구할 때만 개체를 인스턴스화하기 때문에 스프링을 관리해야합니다. }} 인쇄 결과 :
원인 : org.springframework.beans.fackory.beancurrentlyIncreationException : 이름으로 Bean을 생성하는 오류 'a': 요청 된 Bean이 현재 생성 중입니다 : 해결할 수없는 원형 참조가 있습니까?
프로토 타입 모델이 잘못된 이유는 무엇입니까?
"프로토 타입"스코프 콩의 경우, 스프링 컨테이너는 "프로토 타입"스코프 콩의 콩을 캐시하지 않기 때문에 스프링 컨테이너는 의존성 주입을 완료 할 수 없으므로 생성 된 콩을 미리 노출시킬 수 없습니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.