docs/Spring全家桶/Spring源码分析/Spring重要机制探秘/Spring探秘之循环依赖的解决(一):理论基石.md
spring עʱܻע
@Service
public class Service1 {
@Autowired
private Service2 service2;
}
@Service
public class Service2 {
@Autowired
private Service1 service1;
}
ϴ룬 Service1 ͨ @Autowird ע Service2 Service2 ͨ @Autowird ע Service1עͽѭ
ʵϣ ABBҲAjava ȫֵ֧ģ
/**
* service1
*/
public class Service1 {
private Service2 service2;
public void setService2(Service2 service2) {
this.service2 = service2;
}
public Service2 getService2() {
return this.service2;
}
}
/**
* service2
*/
public class Service2 {
private Service1 service1;
public void setService1(Service1 service1) {
this.service1 = service1;
}
public Service1 getService1() {
return this.service1;
}
}
/**
* е
*/
public class Main {
public void main(String[] args) {
//
Service1 service1 = new Service1();
Service2 service2 = new Service2();
//
service1.setService2(service2);
service2.setService1(service1);
}
}
ô spring УעԷʵʲôأ spring bean Ĵ̣ע⣺ǽ bean scope Ϊ singleton Ҳ scope Ϊ``
мҪ˵£
Service1 ΪɼΪ Service1 service = new Service1()Service1 ΪService1 ͨ @Autowired Զע Service2һǸ Service2 ֵḶ́ɼΪ service1.setService2(service2)singletonObjectsһ java ͱһ spring beanȻ浽 singletonObjects ˣǸ map``key bean ƣvalue beanֻ spring beanֻ java ʵʵϣjava spring beanֻע룬гʼִ beanPorcessor ȣڱǷ spring bean ѭģصעѭصIJ衣
˽ spring bean IJ֮Ǿѭ⣬ʽǰȷ
javaʵϣjava һжԳ֮Ϊ java Ϊ˵㣬ᵽ javaָʵɡδ spring bean ڶspring beanһ java ҽ spring bean ڶspring bean Ĵ£
ͼ˵£
service1 ɺspring service1 Ҫע service2Ȼȥ singletonObjects в service2ʱҲ service2ȻͿʼ service2 Ĵ̣service2 ɺspring service2 Ҫע service1Ȼȥ singletonObjects в service1ʱҲ service1Ϊһ service1 ûдɹ ȻͿʼ service1 Ĵ̣1ٴοʼ service1 Ĵע̡Ǿϲط֣ѭˣ
earlySingletonObjects ѭǷ£ѭֵԭڣ service2 ȡ service1 ʱ singletonObjects дʱ service1˻ service1 Ĵ̣´ service1ˣи뷨 service1 ʵͰ service1 ʱͷδע service1
ͼУ earlySingletonObjectsҲǸ mapͬ singletonObjects һkey bean ƣvalue һδעĶ
ͼ˵£
service1 ɺȽ service1 earlySingletonObjectsȻע룻service1 עʱspring service1 Ҫע service2Ȼȥ earlySingletonObjects service2δҵȥ singletonObjects в service2δҵǾͿʼ service2 Ĵ̣service2 ɺȽ service2 earlySingletonObjectsȻע룻service2 עʱspring service2 Ҫע service1Ȼȥ earlySingletonObjects service1ҵˣͽ service1 ע뵽 service2 Уʱ service2 һ spring bean ˣ䱣浽 singletonObjects Уservice2Ȼע뵽 service1 Уʱ service1 Ҳһ spring bean䱣浽 singletonObjects Сϲ裬Ƿ֣ѭõ˽
ķǷֻҪһ earlySingletonObjects ѭܵõǣѭĵõ˽spring ioc ⣬һشܣaop aop ³ѭ
ʽ aop µѭǰȷ
ԭʼڴָδй aop Ķ java Ҳδ aop spring beanspring bean.aop δģ
2.1 е̣aop "ɴ" IJձ浽 singletonObjects еĶҲǴ
ԭʼ֮ʲôϵأôʾ££
public class ProxyObj extends Obj {
// ԭʼ
private Obj obj;
...
}
ʵϣ֮ĹϵûôΪ˵⣬߹ϵ˼СֻҪףԭʼɡ
ԭʼαɴģԲο spring aop ֮ AnnotationAwareAspectJAutoProxyCreator £
ϴ̣ java ģ£
/**
* һ
*/
public class Obj1 {
}
/**
* һ࣬ڲһ Obj1
*/
public class Obj2 {
private Obj1 obj1;
// ʡ
...
}
/**
* Obj2Ĵ࣬ڲobj2Ķ
*/
public class ProxyObj2 extends Obj2 {
private Obj2 obj2;
public ProxyObj2(Obj2 obj2) {
this.obj2 = obj2;
}
// ʡ
...
}
ţģ --> ע --> ɴ --> 浽С ˣ
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// ʼ Obj2 Ĵ
// 1\. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj2 ע obj1ʱûobj1Ҫobj1ٽע뵽Obj2
Obj1 obj1 = new Obj1();
obj2.setObj1(obj1);
// 3\. Obj2Ĵг Obj2ԭʼ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// 4\. proxyObj2Ѿڣ˽ӵʱ
collection.add(proxyObj2);
}
У
new Obj2() ģĴobj2.setObj1(xxx) ģעnew ProxyObj2(xxx) ģcollection.add(xxx) ģӵеĹģ£
obj2Obj2 ע obj1ʱû obj1Ҫ obj1ٽע뵽 Obj2Obj2 Ĵ proxyObj2``proxyObj2 г Obj2 ԭʼproxyObj2 Ѿڣ˽ӵʱϸIJ裬ͻ֣ᷢĵ 2 3 ȫ˳Ҳû⣬ģ£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// ʼ Obj2 Ĵ
// 1\. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj2Ĵг Obj2ԭʼ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// 3\. obj2 ע obj1ʱûobj1Ҫobj1ٽע뵽Obj2
Obj1 obj1 = new Obj1();
// ע뵽ԭʼ
obj2.setObj1(obj1);
// 4\. proxyObj2Ѿڣ˽ӵʱ
collection.add(proxyObj2);
}
£
ӴϿproxyObj2() г ob2(ԭʼ)ɴԭʼע룬ȻӰմеԭʼҲע룬ͼʾ£
ٴ java spring bean IJкö࣬ǽעѭصIJ裬˽ spring bean ϸijʼ̣ɲ鿴 spring ̸֮
̽ڿ֣
ֶܴﵽĿģ浽еǴҴӦԭʼעμ̣Ǻ aop ѭĺģ˵ˣ**aop µѭ֮ܽΪǰ aop **
earlySingletonObjects ѭǰҪ˵˴Ĵ̣ aop £ʹ earlySingletonObjects ѭʲô⣺
ͼ̣
service1 ɺȽ service1 earlySingletonObjectsȻע룻service1 עʱspring service1 Ҫע service2Ȼȥ earlySingletonObjects service2δҵȥ singletonObjects в service2δҵǾͿʼ service2 Ĵ̣service2 ɺȽ service2 earlySingletonObjectsȻע룻service2 עʱspring service2 Ҫע service1Ȼȥ earlySingletonObjects service1ҵˣͽ service1 ע뵽 service2 УȻٽ aopʱ service2 һ䱣浽 singletonObjects Уservice2 ĴȻע뵽 service1 Уٶ service1 aopʱ service1 Ҳһ spring bean䱣浽 singletonObjects Сʲôأϸ 4 ͻ֣ᷢע뵽 service2 service1 Ǵݹȫ֣յõ service1 service2 Ǵע뵽 service2 service1 ӦҲǴŶԡˣ aop £ѭֳˣ
ǰᵽ aop £ earlySingletonObjects ܽѭ⣬ spring ôأspring ٴһ map ⣬Ҳdz˵ **spring ** map ˵£
singletonObjectsΪ ConcurrentHashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value spring beanע롢ʼ bean bean Ҫ aop洢ľǴearlySingletonObjectsΪ HashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value ʵɣδע bean bean Ҫ aop洢ľǴֻеԭʼδע룻singletonFactoriesΪ HashMap<String, ObjectFactory>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value 洢һ lambda ʽ() -> getEarlyBeanReference(beanName, mbd, bean) getEarlyBeanReference е bean Ǹմɵ java beanûн spring ע룬Ҳû aop ( lambda ʽ)Ϊ˵㣬 singletonObjects``earlySingletonObjects singletonFactories ֱΪ**һ**********
spring aop µѭ£
ͼűȽϸӣʵֿͱȽϼˣУ1~8 ǻȡ service1 ̣5.1~5.8 ǻȡ service2 ̣5.5.1 ٴλȡ service1 ֻ̣ڴ service1 ijʼУᴥ service2 ijʼ̣ service2 ijʼʱֻ service1˲ſһ𣬱Ƚϸӡ
ͼḶ́˵£飺̱Ƚϸӣȿ 1~8 IJٿ 5.1~5.8 IJࣩܶ
service1ȡ service1һлȡʱǻȡģservice1 service1 ʵservice1ȡҪע뷽ԭʼϽлȡservice1֧ѭãͽ service1 ŵУǷ֧ѭǿõģservice1 service1 ע룬Ҫ service2ȻͿʼ service2 Ļȡ̣service2ȡ service2һлȡʱǻȡģservice2 service2 ʵservice2ȡҪע뷽ԭʼϽлȡservice2֧ѭãͽ service2 ŵУǷ֧ѭǿõģservice2 service2 ע룬Ҫ service1ȻͿʼ service1 Ļȡ̣service1: ȡ service1һлȡȡʱ service1 ڴУǼӶлȡմлȡˣ档ȡĹУ**ж service1 ǷҪ aopȻʼ aop **˷е service1 ǰ aop ǽѭĹؼservice2õ service1 service1 Ǵע뵽 service2 УŶ service2 aopõ service2 Ĵservice2֧ѭȴһٴλȡ service2δȡʹõǰ service2ǰ service2 Ǵ)service2 service2 ĴһУɾ棬ˣservice2 ʼɣע service1 Ǵһе service2 ҲǴservice1ص service1 ڣõ service2 service2 Ǵע뵽 service1``service1 עɣгʼж service1 ǷҪ aopȻ service1 Ҫ aop ģ 5.5.1 Ѿй aop ˣˣֱӷأһservice1 ԭʼservice1֧ѭȴһлȡ service1ȡٴӶлȡ service1Իȡ 5.5.1 ֪ service1 أservice1лȡĶעᵽһУɾ棬ˣservice1 ʼɣע service2 Ǵһе service1 ҲǴ̣Ȼ϶࣬ service1 service2 ĻȡͬģֻҪŪ֮һĻȡ̣һ bean Ļȡ̾ͺͬˡ
УݽṹҪ˵£
singletonsCurrentlyInCreationΪ SetFromMap<String>λ DefaultSingletonBeanRegistryʽΪ Collections.newSetFromMap(new ConcurrentHashMap<>(16))Ǹ ConcurrentHashMap ʵֵ set洢ڴеĶ**жϵǰǷڴоͨҵǰǷ set **ģearlyProxyReferencesΪ ConcurrentHashMap<Object, Object>λ AbstractAutoProxyCreator洢ǰ aop Ķһǰ aopںٴ aop ʱͨж϶Ƿ earlyProxyReferences жȷҪҪ aopԴ֤ÿֻһ aopˣspring һṩ 5 ݽṹѭ⣬ܽ£
| ṹ | ˵ |
|---|---|
singletonObjects | һΪ ConcurrentHashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value spring beanע롢ʼ bean bean Ҫ aop洢ľǴ |
earlySingletonObjects | Ϊ HashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value ʵɣδע bean bean Ҫ aop洢ľǴֻеԭʼδע |
singletonFactories | ****Ϊ HashMap<String, ObjectFactory>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value 洢һ lambda ʽ() -> getEarlyBeanReference(beanName, mbd, bean)``getEarlyBeanReference(xxx) е bean Ǹմɵ java beanûн spring ע룬Ҳû aop |
singletonsCurrentlyInCreation | Ϊ SetFromMap<String>λ DefaultSingletonBeanRegistryʽΪ Collections.newSetFromMap(new ConcurrentHashMap<>(16))Ǹ ConcurrentHashMap ʵֵ set洢ڴеĶжϵǰǷڴ |
earlyProxyReferences | Ϊ ConcurrentHashMap<Object, Object>λ AbstractAutoProxyCreator洢ǰ aop Ķж bean Ƿй aop֤ÿֻһ aop |
Ͼ spring ѭˡ
ʽԴǰģѭḶ́£
/**
* һ࣬ڲһ Obj2
*/
public class Obj1 {
// Ҫע obj2
private Obj2 obj2;
// ʡ
...
}
/**
* һ࣬ڲһ Obj1
*/
public class Obj2 {
// Ҫע ob1
private Obj1 obj1;
// ʡ
...
}
/**
* Obj2Ĵ࣬ڲobj2Ķ
*/
public class ProxyObj2 extends Obj2 {
// obj2ڲobj2ԭʼ
private Obj2 obj2;
public ProxyObj2(Obj2 obj2) {
this.obj2 = obj2;
}
// ʡ
...
}
/**
* Obj1Ĵ࣬ڲobj1Ķ
*/
public class ProxyObj1 extends Obj1 {
// obj2ڲobj1ԭʼ
private Obj1 obj1;
public ProxyObj1(Obj1 obj1) {
this.obj1 = obj1;
}
// ʡ
...
}
Obj1 Obj2 Obj1 иΪ Obj2``Obj2 иΪ Obj1Obj1 Obj2 Ĵ ProxyObj1``ProxyObj2 ProxyObj1``ProxyObj2 ֱһԣObj1 Obj2new ObjX() ģĴobjX.setObjX(xxx) ģע룻new ProxyObjX(xxx) ģɣcollection.add(xxx) ģӵеḶ́ģյõĽΪ
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2ѾˣǾͿʼģˡ
Ҫ
Ŀ꣺
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// 1\. Obj1
Obj1 obj1 = new Obj1();
// Ҫobj2Ĵע뵽obj1Уʱвûobj2Ĵлobj2Ĵ
// һ. Obj2
Obj2 obj2 = new Obj2();
// obj2Ҫעobj1Ĵʱвûobj2ĴҪеobj1Ĵ
}
ִ ִ Obj2 ̾ͽвȥˣ
obj1 Ҫע obj2 ĴҲл obj2 Ĵ̣obj2 Ҫע obj1 ĴҲл obj1 Ĵ̣obj1 Ҫע obj2 ĴҲл obj2 Ĵ̣ѭ
ģδﵽԤĿ꣬ģʧܡ
Ҫ
Ŀ꣺
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2### 1. ʲôѭspring עʱܻע
@Service
public class Service1 {
@Autowired
private Service2 service2;
}
@Service
public class Service2 {
@Autowired
private Service1 service1;
}
ϴ룬 Service1 ͨ @Autowird ע Service2 Service2 ͨ @Autowird ע Service1עͽѭ
ʵϣ ABBҲAjava ȫֵ֧ģ
/**
* service1
*/
public class Service1 {
private Service2 service2;
public void setService2(Service2 service2) {
this.service2 = service2;
}
public Service2 getService2() {
return this.service2;
}
}
/**
* service2
*/
public class Service2 {
private Service1 service1;
public void setService1(Service1 service1) {
this.service1 = service1;
}
public Service1 getService1() {
return this.service1;
}
}
/**
* е
*/
public class Main {
public void main(String[] args) {
//
Service1 service1 = new Service1();
Service2 service2 = new Service2();
//
service1.setService2(service2);
service2.setService1(service1);
}
}
ô spring УעԷʵʲôأ spring bean Ĵ̣ע⣺ǽ bean scope Ϊ singleton Ҳ scope Ϊ``
мҪ˵£
Service1 ΪɼΪ Service1 service = new Service1()Service1 ΪService1 ͨ @Autowired Զע Service2һǸ Service2 ֵḶ́ɼΪ service1.setService2(service2)singletonObjectsһ java ͱһ spring beanȻ浽 singletonObjects ˣǸ map``key bean ƣvalue beanֻ spring beanֻ java ʵʵϣjava spring beanֻע룬гʼִ beanPorcessor ȣڱǷ spring bean ѭģصעѭصIJ衣
˽ spring bean IJ֮Ǿѭ⣬ʽǰȷ
javaʵϣjava һжԳ֮Ϊ java Ϊ˵㣬ᵽ javaָʵɡδ spring bean ڶspring beanһ java ҽ spring bean ڶspring bean Ĵ£
ͼ˵£
service1 ɺspring service1 Ҫע service2Ȼȥ singletonObjects в service2ʱҲ service2ȻͿʼ service2 Ĵ̣service2 ɺspring service2 Ҫע service1Ȼȥ singletonObjects в service1ʱҲ service1Ϊһ service1 ûдɹ ȻͿʼ service1 Ĵ̣1ٴοʼ service1 Ĵע̡Ǿϲط֣ѭˣ
earlySingletonObjects ѭǷ£ѭֵԭڣ service2 ȡ service1 ʱ singletonObjects дʱ service1˻ service1 Ĵ̣´ service1ˣи뷨 service1 ʵͰ service1 ʱͷδע service1
ͼУ earlySingletonObjectsҲǸ mapͬ singletonObjects һkey bean ƣvalue һδעĶ
ͼ˵£
service1 ɺȽ service1 earlySingletonObjectsȻע룻service1 עʱspring service1 Ҫע service2Ȼȥ earlySingletonObjects service2δҵȥ singletonObjects в service2δҵǾͿʼ service2 Ĵ̣service2 ɺȽ service2 earlySingletonObjectsȻע룻service2 עʱspring service2 Ҫע service1Ȼȥ earlySingletonObjects service1ҵˣͽ service1 ע뵽 service2 Уʱ service2 һ spring bean ˣ䱣浽 singletonObjects Уservice2Ȼע뵽 service1 Уʱ service1 Ҳһ spring bean䱣浽 singletonObjects Сϲ裬Ƿ֣ѭõ˽
ķǷֻҪһ earlySingletonObjects ѭܵõǣѭĵõ˽spring ioc ⣬һشܣaop aop ³ѭ
ʽ aop µѭǰȷ
ԭʼڴָδй aop Ķ java Ҳδ aop spring beanspring bean.aop δģ
2.1 е̣aop "ɴ" IJձ浽 singletonObjects еĶҲǴ
ԭʼ֮ʲôϵأôʾ££
public class ProxyObj extends Obj {
// ԭʼ
private Obj obj;
...
}
ʵϣ֮ĹϵûôΪ˵⣬߹ϵ˼СֻҪףԭʼɡ
ԭʼαɴģԲο spring aop ֮ AnnotationAwareAspectJAutoProxyCreator £
ϴ̣ java ģ£
/**
* һ
*/
public class Obj1 {
}
/**
* һ࣬ڲһ Obj1
*/
public class Obj2 {
private Obj1 obj1;
// ʡ
...
}
/**
* Obj2Ĵ࣬ڲobj2Ķ
*/
public class ProxyObj2 extends Obj2 {
private Obj2 obj2;
public ProxyObj2(Obj2 obj2) {
this.obj2 = obj2;
}
// ʡ
...
}
ţģ --> ע --> ɴ --> 浽С ˣ
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// ʼ Obj2 Ĵ
// 1\. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj2 ע obj1ʱûobj1Ҫobj1ٽע뵽Obj2
Obj1 obj1 = new Obj1();
obj2.setObj1(obj1);
// 3\. Obj2Ĵг Obj2ԭʼ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// 4\. proxyObj2Ѿڣ˽ӵʱ
collection.add(proxyObj2);
}
У
new Obj2() ģĴobj2.setObj1(xxx) ģעnew ProxyObj2(xxx) ģcollection.add(xxx) ģӵеĹģ£
obj2Obj2 ע obj1ʱû obj1Ҫ obj1ٽע뵽 Obj2Obj2 Ĵ proxyObj2``proxyObj2 г Obj2 ԭʼproxyObj2 Ѿڣ˽ӵʱϸIJ裬ͻ֣ᷢĵ 2 3 ȫ˳Ҳû⣬ģ£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// ʼ Obj2 Ĵ
// 1\. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj2Ĵг Obj2ԭʼ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// 3\. obj2 ע obj1ʱûobj1Ҫobj1ٽע뵽Obj2
Obj1 obj1 = new Obj1();
// ע뵽ԭʼ
obj2.setObj1(obj1);
// 4\. proxyObj2Ѿڣ˽ӵʱ
collection.add(proxyObj2);
}
£
ӴϿproxyObj2() г ob2(ԭʼ)ɴԭʼע룬ȻӰմеԭʼҲע룬ͼʾ£
ٴ java spring bean IJкö࣬ǽעѭصIJ裬˽ spring bean ϸijʼ̣ɲ鿴 spring ̸֮
̽ڿ֣
ֶܴﵽĿģ浽еǴҴӦԭʼעμ̣Ǻ aop ѭĺģ˵ˣ**aop µѭ֮ܽΪǰ aop **
earlySingletonObjects ѭǰҪ˵˴Ĵ̣ aop £ʹ earlySingletonObjects ѭʲô⣺
ͼ̣
service1 ɺȽ service1 earlySingletonObjectsȻע룻service1 עʱspring service1 Ҫע service2Ȼȥ earlySingletonObjects service2δҵȥ singletonObjects в service2δҵǾͿʼ service2 Ĵ̣service2 ɺȽ service2 earlySingletonObjectsȻע룻service2 עʱspring service2 Ҫע service1Ȼȥ earlySingletonObjects service1ҵˣͽ service1 ע뵽 service2 УȻٽ aopʱ service2 һ䱣浽 singletonObjects Уservice2 ĴȻע뵽 service1 Уٶ service1 aopʱ service1 Ҳһ spring bean䱣浽 singletonObjects Сʲôأϸ 4 ͻ֣ᷢע뵽 service2 service1 Ǵݹȫ֣յõ service1 service2 Ǵע뵽 service2 service1 ӦҲǴŶԡˣ aop £ѭֳˣ
ǰᵽ aop £ earlySingletonObjects ܽѭ⣬ spring ôأspring ٴһ map ⣬Ҳdz˵ **spring ** map ˵£
singletonObjectsΪ ConcurrentHashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value spring beanע롢ʼ bean bean Ҫ aop洢ľǴearlySingletonObjectsΪ HashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value ʵɣδע bean bean Ҫ aop洢ľǴֻеԭʼδע룻singletonFactoriesΪ HashMap<String, ObjectFactory>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value 洢һ lambda ʽ() -> getEarlyBeanReference(beanName, mbd, bean) getEarlyBeanReference е bean Ǹմɵ java beanûн spring ע룬Ҳû aop ( lambda ʽ)Ϊ˵㣬 singletonObjects``earlySingletonObjects singletonFactories ֱΪ**һ**********
spring aop µѭ£
ͼűȽϸӣʵֿͱȽϼˣУ1~8 ǻȡ service1 ̣5.1~5.8 ǻȡ service2 ̣5.5.1 ٴλȡ service1 ֻ̣ڴ service1 ijʼУᴥ service2 ijʼ̣ service2 ijʼʱֻ service1˲ſһ𣬱Ƚϸӡ
ͼḶ́˵£飺̱Ƚϸӣȿ 1~8 IJٿ 5.1~5.8 IJࣩܶ
service1ȡ service1һлȡʱǻȡģservice1 service1 ʵservice1ȡҪע뷽ԭʼϽлȡservice1֧ѭãͽ service1 ŵУǷ֧ѭǿõģservice1 service1 ע룬Ҫ service2ȻͿʼ service2 Ļȡ̣service2ȡ service2һлȡʱǻȡģservice2 service2 ʵservice2ȡҪע뷽ԭʼϽлȡservice2֧ѭãͽ service2 ŵУǷ֧ѭǿõģservice2 service2 ע룬Ҫ service1ȻͿʼ service1 Ļȡ̣service1: ȡ service1һлȡȡʱ service1 ڴУǼӶлȡմлȡˣ档ȡĹУ**ж service1 ǷҪ aopȻʼ aop **˷е service1 ǰ aop ǽѭĹؼservice2õ service1 service1 Ǵע뵽 service2 УŶ service2 aopõ service2 Ĵservice2֧ѭȴһٴλȡ service2δȡʹõǰ service2ǰ service2 Ǵ)service2 service2 ĴһУɾ棬ˣservice2 ʼɣע service1 Ǵһе service2 ҲǴservice1ص service1 ڣõ service2 service2 Ǵע뵽 service1``service1 עɣгʼж service1 ǷҪ aopȻ service1 Ҫ aop ģ 5.5.1 Ѿй aop ˣˣֱӷأһservice1 ԭʼservice1֧ѭȴһлȡ service1ȡٴӶлȡ service1Իȡ 5.5.1 ֪ service1 أservice1лȡĶעᵽһУɾ棬ˣservice1 ʼɣע service2 Ǵһе service1 ҲǴ̣Ȼ϶࣬ service1 service2 ĻȡͬģֻҪŪ֮һĻȡ̣һ bean Ļȡ̾ͺͬˡ
УݽṹҪ˵£
singletonsCurrentlyInCreationΪ SetFromMap<String>λ DefaultSingletonBeanRegistryʽΪ Collections.newSetFromMap(new ConcurrentHashMap<>(16))Ǹ ConcurrentHashMap ʵֵ set洢ڴеĶ**жϵǰǷڴоͨҵǰǷ set **ģearlyProxyReferencesΪ ConcurrentHashMap<Object, Object>λ AbstractAutoProxyCreator洢ǰ aop Ķһǰ aopںٴ aop ʱͨж϶Ƿ earlyProxyReferences жȷҪҪ aopԴ֤ÿֻһ aopˣspring һṩ 5 ݽṹѭ⣬ܽ£
| ṹ | ˵ |
|---|---|
singletonObjects | һΪ ConcurrentHashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value spring beanע롢ʼ bean bean Ҫ aop洢ľǴ |
earlySingletonObjects | Ϊ HashMap<String, Object>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value ʵɣδע bean bean Ҫ aop洢ľǴֻеԭʼδע |
singletonFactories | ****Ϊ HashMap<String, ObjectFactory>λ DefaultSingletonBeanRegistry Уkey Ϊ beanName``value 洢һ lambda ʽ() -> getEarlyBeanReference(beanName, mbd, bean)``getEarlyBeanReference(xxx) е bean Ǹմɵ java beanûн spring ע룬Ҳû aop |
singletonsCurrentlyInCreation | Ϊ SetFromMap<String>λ DefaultSingletonBeanRegistryʽΪ Collections.newSetFromMap(new ConcurrentHashMap<>(16))Ǹ ConcurrentHashMap ʵֵ set洢ڴеĶжϵǰǷڴ |
earlyProxyReferences | Ϊ ConcurrentHashMap<Object, Object>λ AbstractAutoProxyCreator洢ǰ aop Ķж bean Ƿй aop֤ÿֻһ aop |
Ͼ spring ѭˡ
ʽԴǰģѭḶ́£
/**
* һ࣬ڲһ Obj2
*/
public class Obj1 {
// Ҫע obj2
private Obj2 obj2;
// ʡ
...
}
/**
* һ࣬ڲһ Obj1
*/
public class Obj2 {
// Ҫע ob1
private Obj1 obj1;
// ʡ
...
}
/**
* Obj2Ĵ࣬ڲobj2Ķ
*/
public class ProxyObj2 extends Obj2 {
// obj2ڲobj2ԭʼ
private Obj2 obj2;
public ProxyObj2(Obj2 obj2) {
this.obj2 = obj2;
}
// ʡ
...
}
/**
* Obj1Ĵ࣬ڲobj1Ķ
*/
public class ProxyObj1 extends Obj1 {
// obj2ڲobj1ԭʼ
private Obj1 obj1;
public ProxyObj1(Obj1 obj1) {
this.obj1 = obj1;
}
// ʡ
...
}
Obj1 Obj2 Obj1 иΪ Obj2``Obj2 иΪ Obj1Obj1 Obj2 Ĵ ProxyObj1``ProxyObj2 ProxyObj1``ProxyObj2 ֱһԣObj1 Obj2new ObjX() ģĴobjX.setObjX(xxx) ģע룻new ProxyObjX(xxx) ģɣcollection.add(xxx) ģӵеḶ́ģյõĽΪ
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2ѾˣǾͿʼģˡ
Ҫ
Ŀ꣺
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// 1\. Obj1
Obj1 obj1 = new Obj1();
// Ҫobj2Ĵע뵽obj1Уʱвûobj2Ĵлobj2Ĵ
// һ. Obj2
Obj2 obj2 = new Obj2();
// obj2Ҫעobj1Ĵʱвûobj2ĴҪеobj1Ĵ
}
ִ ִ Obj2 ̾ͽвȥˣ
obj1 Ҫע obj2 ĴҲл obj2 Ĵ̣obj2 Ҫע obj1 ĴҲл obj1 Ĵ̣obj1 Ҫע obj2 ĴҲл obj2 Ĵ̣ѭ
ģδﵽԤĿ꣬ģʧܡ
Ҫ
Ŀ꣺
proxyObj1``proxyObj2obj1 е proxyObj2ע뵽 obj2 е proxyObj2ʾ£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// 1\. Obj1
Obj1 obj1 = new Obj1();
// Ҫobj2Ĵע뵽obj1Уʱвûobj2Ĵлobj2Ĵ
// һ. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj1 ǰ
ProxyObj1 proxyObj1 = new ProxyObj1(obj1);
// . proxyObj1 ע뵽 obj2
obj2.setObj1(proxyObj1);
// . obj2Ĵ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// . proxyObj2 Ѿڣӵʱ
collection.add(proxyObj2);
// ʱѾ obj2 Ĵˣobj1
// 3\. proxyObj2 ע뵽 obj1
obj1.setObj2(proxyObj2);
// 4\. proxyObj1 Ѿڣӵʱ
collection.add(proxyObj1);
}
ĴУobj1 1234 ʶobj2 һġ ʶ£
߶УﵽԤڵĿꡣ
Աģ룬ģ 2 ֮ ܴﵽԤĿ꣬ҪΪע obj2 obj1 ʱǰ obj1 Ĵ proxyObj1ʹ obj2 ̡ٴ֤ṩ aop ѭĽҪã
ƪľȵˣҪѭIJ spring ѭIJ裬ͨδģѭĽһƪǽ spring Դ spring νѭġ
ԭӣhttps://my.oschina.net/funcy/blog/4659555 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע
ʾ£
public static main(String[] args) {
// һﱣڵĶ
// 1\. ԪԭʼöѾע
// 2\. ԪǴöеԭжѾע
Collection<?> collection = new ArrayList();
// 1\. Obj1
Obj1 obj1 = new Obj1();
// Ҫobj2Ĵע뵽obj1Уʱвûobj2Ĵлobj2Ĵ
// һ. Obj2
Obj2 obj2 = new Obj2();
// 2\. Obj1 ǰ
ProxyObj1 proxyObj1 = new ProxyObj1(obj1);
// . proxyObj1 ע뵽 obj2
obj2.setObj1(proxyObj1);
// . obj2Ĵ
ProxyObj2 proxyObj2 = new ProxyObj2(obj2);
// . proxyObj2 Ѿڣӵʱ
collection.add(proxyObj2);
// ʱѾ obj2 Ĵˣobj1
// 3\. proxyObj2 ע뵽 obj1
obj1.setObj2(proxyObj2);
// 4\. proxyObj1 Ѿڣӵʱ
collection.add(proxyObj1);
}
ĴУobj1 1234 ʶobj2 һġ ʶ£
߶УﵽԤڵĿꡣ
Աģ룬ģ 2 ֮ ܴﵽԤĿ꣬ҪΪע obj2 obj1 ʱǰ obj1 Ĵ proxyObj1ʹ obj2 ̡ٴ֤ṩ aop ѭĽҪã
ƪľȵˣҪѭIJ spring ѭIJ裬ͨδģѭĽһƪǽ spring Դ spring νѭġ
ԭӣhttps://my.oschina.net/funcy/blog/4659555 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע