docs/Spring全家桶/Spring源码分析/Spring重要机制探秘/Spring探秘之循环依赖的解决(二):源码分析.md
spring ֮̽ѭһۻʯһ ᵽ spring ѭ:
Ϊ˳Уspring ṩ 5 ݽṹвĹؼϢ 5 ݽṹ£Ľ 5 ݽṹΪ 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 |
˽Щ֮ǾʽʼԴˡ
еʾ demo λ gitee.com/funcyؼ롣
serviceservice1service2 service ﶼһ
@Service
public class Service1 {
@Autowired
private Service2 service2;
public Service1() {
System.out.println("service1Ĺ췽");
}
/**
* ע @AopAnnotation ˣҪ
*/
@AopAnnotation
public void printAutowired() {
System.out.println("Service1 Autowired:" + service2.getClass());
}
@Override
public String toString() {
return "Service1:" + getClass();
}
}
@Component
public class Service2 {
@Autowired
private Service1 service1;
public Service2() {
System.out.println("service2Ĺ췽");
}
/**
* ע @AopAnnotation ˣҪ
*/
@AopAnnotation
public void printAutowired() {
System.out.println("Service2 Autowired:" + service1.getClass());
}
@Override
public String toString() {
return "Service2:" + this.getClass();
}
}
ࣺ
public class Demo03Main {
public static void main(String[] args) {
ApplicationContext context =
new AnnotationConfigApplicationContext(AopAnnotationConfig.class);
Object obj1 = context.getBean("service1");
Object obj2 = context.getBean("service2");
((Service1)obj1).printAutowired();
((Service2)obj2).printAutowired();
}
}
Service1 УҪע service2 Service2 УҪע service1 Service1``Service2 Ҫд main() ִн£
service1Ĺ췽
service2Ĺ췽
Disconnected from the target VM, address: 'localhost:55518', transport: 'socket'
Connected to the target VM, address: '127.0.0.1:55507', transport: 'socket'
@Around: before execute...
Service1 Autowired:class org.springframework.learn.explore.demo03.Service2$$EnhancerBySpringCGLIB$$e7e367ab
@Around: after execute...
@Around: before execute...
Service2 Autowired:class org.springframework.learn.explore.demo03.Service1$$EnhancerBySpringCGLIB$$d447df08
@Around: after execute...
õ obj1obj2 ֱΪ
ݣѵó½ۣ
service1 service2 printAutowired() 淽ݣ߶ɹˣservice1 service2 Ǵservice1 Ĵ service1 ԭʼservice2 Ĵ service2 ԭʼservice1 ԭʼע service2 Ϊservice2 ԭʼע service1 ΪǾʹԴ spring һУյõġ
service1service2Ĵcglibģⲿ뱾أͲˡ
AbstractBeanFactory#getBean(String)ȡ service1spring bean ĴעǴ AbstractBeanFactory#getBean(String) ʼһɲο spring ֮ BeanFactory ijʼǵԴҲ֡
һʼᵽ spring Ϊѭ 5 ṹչʾ£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | |
singletonsCurrentlyInCreation | |
earlyProxyReferences |
һʼ5 ṹй service1 service2 ʲôݶû һ߷룬һ߹ע⼸ṹеݡ
ʵϣ5 ṹݵģ spring ڲṩһЩ beanֻע
service1service2صݣﲻչʾ
AbstractBeanFactory#doGetBeanȡ service1 Ĵ AbstractBeanFactory#getBean(String)Ļȡȴ AbstractBeanFactory#doGetBean У£
|-AbstractBeanFactory#getBean(String)
|-AbstractBeanFactory#doGetBean
£
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...
// 1\. ǷѳʼbeanNamesingletonsCurrentlyInCreation
Object sharedInstance = getSingleton(beanName);
...
// ǵ
if (mbd.isSingleton()) {
// 2\. getSingleton(): ɾ
sharedInstance = getSingleton(beanName, () -> {
try {
// ִд Bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
// ͨBean Ļֱӷأ FactoryBean Ļ
// Ǹʵ
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
...
}
ϴ뾭˾ֻҪ̣УҲᾫ룬ֻҪ̣ʡش룩طҪ
getSingleton(beanName)ȡֻлȡgetSingleton(beanName, () -> { ... })ȡﴴDefaultSingletonBeanRegistry#getSingleton(String, boolean)getSingleton(beanName)£
|-AbstractBeanFactory#getBean(String)
|-AbstractBeanFactory#doGetBean
|-DefaultSingletonBeanRegistry#getSingleton(String)
|-DefaultSingletonBeanRegistry#getSingleton(String, boolean)
ֱӿ룺
/*
* beanName: ֵΪ service1
* allowEarlyReferenceֵΪ true
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1\. һлȡǻȡ
Object singletonObject = this.singletonObjects.get(beanName);
// 2\. isSingletonCurrentlyInCreation(...) жservice1ǷڴУ false
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
// ʡĴ
...
}
return singletonObject;
}
£
лȡʱ singletonObjects ﲢû service1ȡ
ж service1 ǷڴУжϷʽ£
public boolean isSingletonCurrentlyInCreation(String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}
ȻsingletonsCurrentlyInCreation û service1 ģҲ false.
DefaultSingletonBeanRegistry#getSingleton(String, boolean) еͷˣķǾȲˡ
DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)ǻص AbstractBeanFactory#doGetBeanŷ getSingleton(beanName, () -> { ... })£
/**
* beanNameservice1
* singletonFactorylambdaʽֵΪ
* () -> {
* try {
* // Ǵbean
* return createBean(beanName, mbd, args);
* }
* catch (BeansException ex) {
* destroySingleton(beanName);
* throw ex;
* }
* }
*/
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
// ٴжbeanǷѴ
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
// 1\. жϵǰʵbeanǷڴ
// beanNameӵ singletonsCurrentlyInCreation
beforeSingletonCreation(beanName);
try {
// 2\. beanĴ
singletonObject = singletonFactory.getObject();
}
catch (...) {
...
}
...
}
return singletonObject;
}
}
մеעݣǷҪ裺
жϵǰʵ bean ǷڴУжϵǰǷ singletonsCurrentlyInCreation У׳쳣ӵ singletonsCurrentlyInCreation У
֮һд5 ṹе£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences |
bean Ĵ̣singletonFactory.getObject() еʵǴ lambda ʽ
() -> {
try {
// ִд Bean
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
Ҳ AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) ǽص㣻
AbstractAutowireCapableBeanFactory#doCreateBeanӴAbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) ûʲôʵݣǾֱ AbstractAutowireCapableBeanFactory#doCreateBean ˣоǧɽˮ£
|-AbstractBeanFactory#getBean(String)
|-AbstractBeanFactory#doGetBean
|-DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)
|-AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
|-AbstractAutowireCapableBeanFactory#doCreateBean
AbstractAutowireCapableBeanFactory#doCreateBean £
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
BeanWrapper instanceWrapper = null;
if (instanceWrapper == null) {
// 1\. ʵ Beanjavaʵ
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//beanʵ
final Object bean = instanceWrapper.getWrappedInstance();
//bean
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
// AutowiredAnnotationBeanPostProcessor#postProcessMergedBeanDefinition
// 2\. ȡҪע뷽ע @Autowired ע⣩
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// ѭ, Ƿѭ, allowCircularReferencesĬΪtrueԹر
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
// 3\. bean ӵ singletonFactories
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
Object exposedObject = bean;
try {
// 4\. ע룬Ҫע service2Ȼٵ getBean("service2")
populateBean(beanName, mbd, instanceWrapper);
...
}
catch (Throwable ex) {
...
}
}
еIJ£
ʵ Bean java ʵͲ˵ˣʵ service1 £Կ service2 nullδע룩
ȡҪע뷽ԭʼвܻȡǻȡ @Autowired beanPostProcessor AutowiredAnnotationBeanPostProcessor
bean ӵ singletonFactories Уӹ£
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
// صвڲŻadd
if (!this.singletonObjects.containsKey(beanName)) {
// ѹputsingletonFactories
this.singletonFactories.put(beanName, singletonFactory);
// ɾеĶ
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
ĶΪ
ʱ 5 ṹе£
| ṹ | |
| ------------------------------- | ---------------- |
| singletonObjects | |
| earlySingletonObjects | |
| singletonFactories | lambda(service1) |
| singletonsCurrentlyInCreation | service1 |
| earlyProxyReferences | |
lambda(service1) ʵΪ () -> getEarlyBeanReference(beanName, mbd, bean) lambda ʽľǽ aop ݵеʱٷ
ע룬ڵ 2 Уspring ҵ service1 Ҫע service2ٵ beanFactory.getBean("service2") service2 ڣֻص AbstractBeanFactory#getBean(String)
populateBean(xxx) getBean(xxx) IJ൱࣬£
|-AbstractBeanFactory#getBean(String)
|-AbstractBeanFactory#doGetBean
|-DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)
|-AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
|-AbstractAutowireCapableBeanFactory#doCreateBean
// ע
|-AbstractAutowireCapableBeanFactory#populateBean
|-AutowiredAnnotationBeanPostProcessor#postProcessProperties
|-InjectionMetadata#inject
|-AutowiredAnnotationBeanPostProcessor.AutowiredFieldElement#inject
|-DefaultListableBeanFactory#resolveDependency
|-DefaultListableBeanFactory#doResolveDependency
|-DependencyDescriptor#resolveCandidate
|-AbstractBeanFactory#getBean(String)
һ DependencyDescriptor#resolveCandidateõ beanFactory.getBean(String)
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName);
}
service1 Ļȡ̾ͣһ£Ϊ service1 Ҫע service2Ϳʼȡ service2 ̡
Сڽʱ5 ṹе£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | lambda(service1) |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences |
AbstractBeanFactory#getBean(String)ȡ service2AbstractBeanFactory#doGetBeanһȡ service1 ̻һ£ͬ beanName service2ٷ
DefaultSingletonBeanRegistry#getSingleton(String, boolean)һȡ service1 ̻һ£ͬ beanName service2ٷ
DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)һȡ service1 ̻һ£ͬ beanName service2ݲٷ
service2 һ singletonsCurrentlyInCreation ṹУһ֮5 ṹе£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | lambda(service1) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences |
AbstractAutowireCapableBeanFactory#doCreateBeanһȡ service1 ̻һ£˵£
ᴴ service2ɺĶ£
ͬģservice2 е service1 ҲΪ null
ȡҪע뷽service2 service1 ᱻҵΪԱע @Autowired ע⣻
bean ӵ singletonFactories Уһ֮5 ṹе£
| ṹ | |
| ------------------------------- | ---------------------------------- |
| singletonObjects | |
| earlySingletonObjects | |
| singletonFactories | lambda(service1), lambda(service2) |
| singletonsCurrentlyInCreation | service1, service2 |
| earlyProxyReferences | |
һĹؼڣservice2 ӵˣ
service2 Ҫע service1ٵ getBean("service2") ֻص AbstractBeanFactory#getBean(String) ˡservice2 ĻȡҲҪͣһˣΪ service2 Ҫע service1Ҫʼȡ service1 ̡
Сڽʱ5 ṹе£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | lambda(service1), lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences |
AbstractBeanFactory#getBean(String)ٴλȡ service1AbstractBeanFactory#doGetBeanAbstractBeanFactory#doGetBean £
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...
// 1\. ǷѳʼbeanNamesingletonsCurrentlyInCreation
Object sharedInstance = getSingleton(beanName);
...
}
е Object sharedInstance = getSingleton(beanName) ǰAbstractBeanFactory#doGetBean ǰС Object sharedInstance = getSingleton(beanName) ˱仯 getSingleton(beanName) ִС
DefaultSingletonBeanRegistry#getSingleton(String, boolean)/*
* beanName: ֵΪ service1
* allowEarlyReferenceֵΪ true
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1\. һлȡǻȡ
Object singletonObject = this.singletonObjects.get(beanName);
// 2\. isSingletonCurrentlyInCreation(...) жservice1ǷڴУ true
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 3\. ӶлȡҲȡ
singletonObject = this.earlySingletonObjects.get(beanName);
// 4\. allowEarlyReferencetrueִ
if (singletonObject == null && allowEarlyReference) {
// 5\. лȡܻȡ
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 6\. singletonFactory.getObject()
// յõ AbstractAutowireCapableBeanFactory.getEarlyBeanReference
singletonObject = singletonFactory.getObject();
// 7\.
// ŵ
this.earlySingletonObjects.put(beanName, singletonObject);
//
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
ڷǰʱ 5 ṹеݣ
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | |
singletonFactories | lambda(service1), lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences |
ݣ£
һлȡ 5 ṹеݣȡ null;
isSingletonCurrentlyInCreation(...) ж service1 ǷڴУ 5 ṹеݣservice1 singletonsCurrentlyInCreation У truẹһλȡ service1 IJ֮ͬ
Ӷлȡ 5 ṹеݣservice1 earlySingletonObjectsȻ null
allowEarlyReference ǴIJΪ trueִ Ĵ룻
Ӵлȡ 5 ṹеݣservice1 singletonFactories УܻȡصĽ£
singletonFactory.getObject() Ǵ singletonFactories ĻǸ lambda ʽ() -> getEarlyBeanReference(beanName, mbd, bean) singletonFactory.getObject() յõľ AbstractAutowireCapableBeanFactory#getEarlyBeanReference
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
// úôaop
SmartInstantiationAwareBeanPostProcessor ibp =
(SmartInstantiationAwareBeanPostProcessor) bp;
// `AbstractAutoProxyCreator#getEarlyBeanReference`ǰ aop
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
}
}
}
return exposedObject;
}
Ǹ AbstractAutoProxyCreator#getEarlyBeanReference
public Object getEarlyBeanReference(Object bean, String beanName) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
this.earlyProxyReferences.put(cacheKey, bean);
// ɴ
return wrapIfNecessary(bean, beanName, cacheKey);
}
aop ̣ɲο [spring aop ֮ AnnotationAwareAspectJAutoProxyCreator £](https://my.oschina.net/funcy/blog/4687961)Ͳٷˡִ `AbstractAutoProxyCreator#getEarlyBeanReference` ֮5 ṹе£
| ṹ | |
| ------------------------------- | ---------------------------------- |
| singletonObjects | |
| earlySingletonObjects | |
| singletonFactories | lambda(service1), lambda(service2) |
| singletonsCurrentlyInCreation | service1, service2 |
| earlyProxyReferences | service1 |
ٻص getSingleton ִ singletonFactory.getObject() õ singletonObject Ϊ
һ service2 Ϊ null
DefaultSingletonBeanRegistry#getSingleton(String, boolean) ִɺ5 ṹе£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | service1 |
singletonFactories | lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences | service1 |
AbstractBeanFactory#doGetBeanִ DefaultSingletonBeanRegistry#getSingleton(String, boolean) ٻص AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
...
// Ƿѳʼ
Object sharedInstance = getSingleton(beanName);
// 1\. ܻȡif Ĵִ
if (sharedInstance != null && args == null) {
// 2\. ͨBean Ļֱӷأ FactoryBean ĻǸʵ
// beanservice1Ĵ
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
} else {
// Ĵ벻ִеͲ
...
}
// beanתﷵfalseִе
if (requiredType != null && !requiredType.isInstance(bean)) {
...
}
// 3\. ش`getSingleton(beanName)`õĶ
return bean;
}
ܻȡif ĴִУ
service1 FactoryBean getSingleton(beanName) õĶͬһ£
ش getSingleton(beanName) õĶ getSingleton(beanName) зصĶΪպͲִ bean Ĵˣշصǵ 2 еõ bean ˡ
ڻȡ service1 ĴܴӦԭʼûע룬ȻԽк̣ȡ service1 Ĵservice2 ͿԽע룬ˡ
ִ֮5 ṹеݣ
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences | service1 |
ȡ service1 ͼ service2 Ļȡˡ
service2 Ļȡڵ 3 УΪ service2 Ҫע service1˵ 4 ֵٴλȡ service1 ̣Ҳɹػȡ service1 Ĵ service1$$EnhancerBySpringCGLIB service2 ע롣
3 ̣ص AbstractAutowireCapableBeanFactory#doCreateBean service2 ̡
AbstractAutowireCapableBeanFactory#doCreateBean£
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
// Ĵ 3.2 ѾˣͲٷ
...
Object exposedObject = bean;
try {
// 1\. װ, Ҳdz˵ע
populateBean(beanName, mbd, instanceWrapper);
// 2\. ʼᴦ aop
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
...
}
//ͬģѭ
if (earlySingletonExposure) {
// 3\. ӻлȡ beanName Ӧbean
Object earlySingletonReference = getSingleton(beanName, false);
// 4\. earlySingletonReference Ϊ nullif ݲִ
if (earlySingletonReference != null) {
...
}
}
// ʡԲҪĴ
...
return exposedObject;
}
˵£
ע룬ﴥ˵ 4 ִֵ̣õ service2 £
Կʱע뵽 service2 е service1 Ǵˣ
ʼᴦ aop ִ aop ķΪ AbstractAutoProxyCreator#postProcessAfterInitialization£
// beanΪservice2beanNameΪservice2
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 1\. earlyProxyReferences вû service2ifĴִе
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 2\. ﴦaop
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
ϴȴ earlyProxyReferences Ƴ service2Ȼ봫 bean Ƚϣ 5 ṹеݣǷ service2 earlyProxyReferences У
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences | service1 |
ˣﷵ nullȻڴ bean if еĴִУservice2 aopִһõ exposedObject Ϊ
service2 Ҳ˴ע롣
ӻлȡ beanName Ӧ beanִе DefaultSingletonBeanRegistry#getSingleton(String, boolean)£
/**
* beanName: service2
* allowEarlyReferencefalse
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1\. һлȡ service2ȡnull
Object singletonObject = this.singletonObjects.get(beanName);
// 2\. ж service2 ǷڴУtrueִifеĴ
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 3\. Ӷлȡ service2ȡnull
singletonObject = this.earlySingletonObjects.get(beanName);
// 4\. ʱ allowEarlyReference ΪfalseifĴ벻ִ
if (singletonObject == null && allowEarlyReference) {
...
}
}
}
return singletonObject;
}
ǻ һ 5 ṹеݣִоһĿȻˣ
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | lambda(service2) |
singletonsCurrentlyInCreation | service1, service2 |
earlyProxyReferences | service1 |
ִУڴѾע͵úˣͶ˵ˣ
3 ص earlySingletonReference Ϊ nullif ݲִС
õ service2 ͷˡ
DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)õ service2 bean ǻص DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>) service2 ̣£
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "Bean name must not be null");
synchronized (this.singletonObjects) {
...
try {
// 1\. beanĴ
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (...) {
...
}
finally {
...
// 2\. ɺһЩ
// service2 singletonsCurrentlyInCreation Ƴ
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 3\. öӵ beanFactory Уɾ
addSingleton(beanName, singletonObject);
}
...
return singletonObject;
}
}
˵£
ǧգsingletonFactory.getObject() ִˣ֮ջǵõ service2 Ĵ
service2 ɺͻὫ singletonsCurrentlyInCreation ƳȽϼͲ˵ˣһõ 5 ṹ£
| ṹ | |
|---|---|
singletonObjects | |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | lambda(service2) |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences | service1 |
ţǻĴΪ DefaultSingletonBeanRegistry#addSingleton
/*
* beanNameservice2
* singletonObjectservice2$$EnhancerBySpringCGLIB(service2Ĵ)
*/
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
// putremoveֻһиö
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
ȽϼͲ˵ˣ 5 ṹΪ
| ṹ | |
|---|---|
singletonObjects | service2$$EnhancerBySpringCGLIB |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences | service1 |
ˣservice2 ȡɣձ浽 singletonObjects е bean Ϊ
ڵҲ 5 ṹеݣ
| ṹ | |
|---|---|
singletonObjects | service2$$EnhancerBySpringCGLIB |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences | service1 |
ˣservice2 ȡɣǼ service1 Ļȡ̡
service1 Ļȡڵ 2 УΪ servic1 Ҫע service2˵ 3 ڻȡ service2 ̣Ȼ־һϵеIJڵ 5 ڳɹػȡ service2 Ĵ service2$$EnhancerBySpringCGLIB service2 ע롣
2 ڣص AbstractAutowireCapableBeanFactory#doCreateBean service1 ̡
AbstractAutowireCapableBeanFactory#doCreateBean£
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd,
final @Nullable Object[] args) throws BeanCreationException {
// Ĵ 3.1 ѾˣͲٷ
...
Object exposedObject = bean;
try {
// 1\. װ, Ҳdz˵ע
populateBean(beanName, mbd, instanceWrapper);
// 2\. ʼᴦ aop
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
...
}
//ͬģѭ
if (earlySingletonExposure) {
// 3\. ӻлȡ beanName Ӧbean
Object earlySingletonReference = getSingleton(beanName, false);
// 4\. earlySingletonReference Ϊ nullif ݻִ
if (earlySingletonReference != null) {
if (exposedObject == bean) {
// 5\. صĶֵ exposedObjectضΪ
exposedObject = earlySingletonReference;
}
}
}
// ʡԲҪĴ
...
return exposedObject;
}
˵£
ע룬ﴥ˵ 3 ڵִ̣õ service1 £
Կservice1 Ѿע룬Ҵʱע뵽 service1 е service2 ѾǴˣ service1 ʱԭʼǼ¿
ʼᴦ aop ִ aop ķΪ AbstractAutoProxyCreator#postProcessAfterInitialization£
// beanΪservice1beanNameΪservice1
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
// 1\. earlyProxyReferences service1ifĴ벻ִе
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 2\. ﴦaopservice1 Ѿִйaop
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
ϴȴ earlyProxyReferences Ƴ service1Ȼ봫 bean Ƚϣ 5 ṹеݣǷ service1 ʱ earlyProxyReferences У
| ṹ | |
|---|---|
singletonObjects | service2$$EnhancerBySpringCGLIB |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences | service1 |
ˣ᷵ service1if еĴ벻ִСִһ5 ṹеΪ
| ṹ | |
|---|---|
singletonObjects | service2$$EnhancerBySpringCGLIB |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences |
ӻлȡ beanName Ӧ beanִе DefaultSingletonBeanRegistry#getSingleton(String, boolean)£
/**
* beanName: service1
* allowEarlyReferencefalse
*/
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 1\. һлȡ service1ȡnull
Object singletonObject = this.singletonObjects.get(beanName);
// 2\. ж service1 ǷڴУtrueִifеĴ
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 3\. Ӷлȡ service1ܻȡ
singletonObject = this.earlySingletonObjects.get(beanName);
// 4\. singletonObject ΪnullifĴ벻ִ
if (singletonObject == null && allowEarlyReference) {
...
}
}
}
return singletonObject;
}
ǿ һ 5 ṹеݣִоһĿȻˣ
| ṹ | |
|---|---|
singletonObjects | service2$$EnhancerBySpringCGLIB |
earlySingletonObjects | service1$$EnhancerBySpringCGLIB |
singletonFactories | |
singletonsCurrentlyInCreation | service1 |
earlyProxyReferences |
ִУڴѾע͵úˣͶ˵ˣһ service1 Ĵأ
һõ earlySingletonReference Ϊ
ѾˣԼִ if Ĵˣ
һǸֵصĶֵ exposedObjectȻ exposedObjectշصĶΪ service1 Ĵ
һservice1 ĴҲȡˡ
DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)һIJһЩ棬Ͳٷˣ 5 ṹе£
| ṹ | |
|---|---|
singletonObjects | service2<nobr aria-hidden="true">EnhancerBySpringCGLIB,service1</nobr><math xmlns="http://www.w3.org/1998/Math/MathML" display="block"><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mo>,</mo><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mi>?</mi><mn>1</mn></math><mi>E</mi><mi>n</mi><mi>h</mi><mi>a</mi><mi>n</mi><mi>c</mi><mi>e</mi><mi>r</mi><mi>B</mi><mi>y</mi><mi>S</mi><mi>p</mi><mi>r</mi><mi>i</mi><mi>n</mi><mi>g</mi><mi>C</mi><mi>G</mi><mi>L</mi><mi>I</mi><mi>B</mi><mo>,</mo><mi>s</mi><mi>e</mi><mi>r</mi><mi>v</mi><mi>i</mi><mi>c</mi><mi>e</mi><mn>1</mn></math>" role="presentation">EnhancerBySpringCGLIB |
earlySingletonObjects | |
singletonFactories | |
singletonsCurrentlyInCreation | |
earlyProxyReferences |
ͨԣ鿴õ singletonObjects ж£
service1
service2
ԿsingletonObjects ߶Ǵ˴עģҲǴѭõ˽
spring ѭķͽˣѭнĺǰ aopspring һ㣬 5 ṹ洢ҪϢһѭ⡣
ԭӣhttps://my.oschina.net/funcy/blog/4815992 ߸ˮƽд֮ӭָԭףҵתϵȨҵתע