Back to Javatutorial

Spring探秘之循环依赖的解决(二):源码分析

docs/Spring全家桶/Spring源码分析/Spring重要机制探秘/Spring探秘之循环依赖的解决(二):源码分析.md

1.0.039.7 KB
Original Source

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

˽Щ֮󣬽ǾʽʼԴˡ

1. ׼ demo

еʾ 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 һУյõġ

service1 service2 Ĵ cglib ģⲿ뱾޹أͲˡ

2. һε AbstractBeanFactory#getBean(String)ȡ service1

spring bean ĴעǴ AbstractBeanFactory#getBean(String) ʼһɲο spring ֮ BeanFactory ijʼǵԴҲ֡

һʼᵽ spring Ϊѭ 5 ṹչʾ£

singletonObjects
earlySingletonObjects
singletonFactories
singletonsCurrentlyInCreation
earlyProxyReferences

һʼ5 ṹй service1 service2 ʲôݶû һ߷룬һ߹ע⼸ṹеݡ

ʵϣ5 ṹݵģ spring ڲṩһЩ beanֻע service1 service2 صݣﲻչʾ

2.1 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);
        }
        ...
    }

ϴ뾭˾ֻҪ̣УҲᾫ룬ֻҪ̣ʡ޹ش룩طҪ

  1. getSingleton(beanName)ȡֻлȡ
  2. getSingleton(beanName, () -> { ... })ȡ󣬴ﴴ

2.2 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;
}

£

  1. лȡʱ singletonObjects ﲢû service1ȡ

  2. ж service1 ǷڴУжϷʽ£

    public boolean isSingletonCurrentlyInCreation(String beanName) {
        return this.singletonsCurrentlyInCreation.contains(beanName);
    }
    
    

    ȻsingletonsCurrentlyInCreation û service1 ģҲ false.

DefaultSingletonBeanRegistry#getSingleton(String, boolean) еͷˣķǾȲˡ

2.3 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;
        }
    }

մеעݣǷҪ裺

  1. жϵǰʵ bean ǷڴУжϵǰǷ singletonsCurrentlyInCreation У׳쳣ӵ singletonsCurrentlyInCreation У

    ֮һд5 ṹе£

    singletonObjects
    earlySingletonObjects
    singletonFactories
    singletonsCurrentlyInCreationservice1
    earlyProxyReferences
  2. bean Ĵ̣singletonFactory.getObject() еʵǴ lambda ʽ

() -> {
    try {
        // ִд Bean
        return createBean(beanName, mbd, args);
    }
    catch (BeansException ex) {
        destroySingleton(beanName);
        throw ex;
    }
}

Ҳ AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[]) ǽص㣻

2.4 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£

  1. ʵ Bean java ʵͲ˵ˣʵ service1 £Կ service2 nullδע룩

  2. ȡҪע뷽ԭʼвܻȡǻȡ @Autowired beanPostProcessor AutowiredAnnotationBeanPostProcessor

  3. 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 ݵеʱٷ

  1. ע룬ڵ 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
singletonFactorieslambda(service1)
singletonsCurrentlyInCreationservice1
earlyProxyReferences

3. ڶε AbstractBeanFactory#getBean(String)ȡ service2

3.1 AbstractBeanFactory#doGetBean

һȡ service1 ̻һ£ͬ beanName service2ٷ

3.2 DefaultSingletonBeanRegistry#getSingleton(String, boolean)

һȡ service1 ̻һ£ͬ beanName service2ٷ

3.3 DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)

һȡ service1 ̻һ£ͬ beanName service2ݲٷ

service2 һ singletonsCurrentlyInCreation ṹУһ֮5 ṹе£

singletonObjects
earlySingletonObjects
singletonFactorieslambda(service1)
singletonsCurrentlyInCreationservice1, service2
earlyProxyReferences

3.4 AbstractAutowireCapableBeanFactory#doCreateBean

һȡ service1 ̻һ£˵£

  1. 󴴽ᴴ service2ɺĶ£

    ͬģservice2 е service1 ҲΪ null

  2. ȡҪע뷽service2 service1 ᱻҵΪԱע @Autowired ע⣻

  3. bean ӵ singletonFactories Уһ֮5 ṹе£

| ṹ | | | ------------------------------- | ---------------------------------- | | singletonObjects | | | earlySingletonObjects | | | singletonFactories | lambda(service1), lambda(service2) | | singletonsCurrentlyInCreation | service1, service2 | | earlyProxyReferences | |

һĹؼڣservice2 ӵˣ

  1. ע룬ڵ 2 Уspring ҵ service2 Ҫע service1ٵ getBean("service2") ֻص AbstractBeanFactory#getBean(String) ˡ

service2 ĻȡҲҪͣһˣΪ service2 Ҫע service1Ҫʼȡ service1 ̡

Сڽʱ5 ṹе£

singletonObjects
earlySingletonObjects
singletonFactorieslambda(service1), lambda(service2)
singletonsCurrentlyInCreationservice1, service2
earlyProxyReferences

4. ε AbstractBeanFactory#getBean(String)ٴλȡ service1

4.1 AbstractBeanFactory#doGetBean

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);
        ...
}

е Object sharedInstance = getSingleton(beanName) ǰAbstractBeanFactory#doGetBean ǰС Object sharedInstance = getSingleton(beanName) ˱仯 getSingleton(beanName) ִС

4.2 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
singletonFactorieslambda(service1), lambda(service2)
singletonsCurrentlyInCreationservice1, service2
earlyProxyReferences

ݣ£

  1. һлȡ 5 ṹеݣȡ null;

  2. isSingletonCurrentlyInCreation(...) ж service1 ǷڴУ 5 ṹеݣservice1 singletonsCurrentlyInCreation У truẹһλȡ service1 IJ֮ͬ

  3. Ӷлȡ 5 ṹеݣservice1 earlySingletonObjectsȻ null

  4. allowEarlyReference ǴIJΪ trueִ Ĵ룻

  5. Ӵлȡ 5 ṹеݣservice1 singletonFactories УܻȡصĽ£

  6. 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

  1. ǴˣһЩ map put remove Ͳ˵ˡ

DefaultSingletonBeanRegistry#getSingleton(String, boolean) ִɺ5 ṹе£

singletonObjects
earlySingletonObjectsservice1
singletonFactorieslambda(service2)
singletonsCurrentlyInCreationservice1, service2
earlyProxyReferencesservice1

4.3 ٴλص 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;

}

  1. ܻȡif ĴִУ

  2. service1 FactoryBean getSingleton(beanName) õĶͬһ£

  3. ش getSingleton(beanName) õĶ getSingleton(beanName) зصĶΪպ󣬾Ͳִ bean Ĵˣշصǵ 2 еõ bean ˡ

ڻȡ service1 Ĵ󣬾ܴӦԭʼûע룬ȻԽк̣ȡ service1 Ĵservice2 ͿԽע룬ˡ

ִ֮5 ṹеݣ

singletonObjects
earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
singletonFactorieslambda(service2)
singletonsCurrentlyInCreationservice1, service2
earlyProxyReferencesservice1

ȡ service1 󣬽ͼ service2 Ļȡˡ

5 service2 Ļȡ

ڵ 3 УΪ service2 Ҫע service1˵ 4 ֵٴλȡ service1 ̣Ҳɹػȡ service1 Ĵ service1$$EnhancerBySpringCGLIB service2 ע롣

3 ̣ص AbstractAutowireCapableBeanFactory#doCreateBean service2 ̡

5.1 ص 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;
    }

˵£

  1. ע룬ﴥ˵ 4 ִֵ̣õ service2 £

    Կʱע뵽 service2 е service1 Ǵˣ

  2. ʼᴦ 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
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactorieslambda(service2)
    singletonsCurrentlyInCreationservice1, service2
    earlyProxyReferencesservice1

    ˣﷵ nullȻڴ bean if еĴִУservice2 aopִһ󣬵õ exposedObject Ϊ

    service2 Ҳ˴ע롣

  3. ӻлȡ 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
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactorieslambda(service2)
    singletonsCurrentlyInCreationservice1, service2
    earlyProxyReferencesservice1

    ִУڴѾע͵úˣͶ˵ˣ

  4. 3 ص earlySingletonReference Ϊ nullif ݲִС

õ service2 ͷˡ

5.2 ص 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;
    }
}

˵£

  1. ǧգsingletonFactory.getObject() ִˣ֮ջǵõ service2 Ĵ

  2. service2 ɺ󣬾ͻὫ singletonsCurrentlyInCreation ƳȽϼ򵥣Ͳ˵ˣһõ 5 ṹ£

    singletonObjects
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactorieslambda(service2)
    singletonsCurrentlyInCreationservice1
    earlyProxyReferencesservice1
  3. ţǻĴΪ 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 ṹΪ

    singletonObjectsservice2$$EnhancerBySpringCGLIB
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactories
    singletonsCurrentlyInCreationservice1
    earlyProxyReferencesservice1

ˣservice2 ȡɣձ浽 singletonObjects е bean Ϊ

ڵҲ 5 ṹеݣ

singletonObjectsservice2$$EnhancerBySpringCGLIB
earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
singletonFactories
singletonsCurrentlyInCreationservice1
earlyProxyReferencesservice1

ˣservice2 ȡɣǼ service1 Ļȡ̡

6 service1 Ļȡ

ڵ 2 УΪ servic1 Ҫע service2˵ 3 ڻȡ service2 ̣Ȼ־һϵеIJڵ 5 ڳɹػȡ service2 Ĵ service2$$EnhancerBySpringCGLIB service2 ע롣

2 ڣص AbstractAutowireCapableBeanFactory#doCreateBean service1 ̡

6.1 ص 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;
    }

˵£

  1. ע룬ﴥ˵ 3 ڵִ̣õ service1 £

    Կservice1 Ѿע룬Ҵʱע뵽 service1 е service2 ѾǴˣ service1 ʱԭʼǼ¿

  2. ʼᴦ 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 У

    singletonObjectsservice2$$EnhancerBySpringCGLIB
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactories
    singletonsCurrentlyInCreationservice1
    earlyProxyReferencesservice1

    ˣ᷵ service1if еĴ벻ִСִһ5 ṹеΪ

    singletonObjectsservice2$$EnhancerBySpringCGLIB
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactories
    singletonsCurrentlyInCreationservice1
    earlyProxyReferences
  3. ӻлȡ 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 ṹеݣִоһĿȻˣ

    singletonObjectsservice2$$EnhancerBySpringCGLIB
    earlySingletonObjectsservice1$$EnhancerBySpringCGLIB
    singletonFactories
    singletonsCurrentlyInCreationservice1
    earlyProxyReferences

    ִУڴѾע͵úˣͶ˵ˣһ service1 Ĵ󷵻أ

  4. һõ earlySingletonReference Ϊ

    ѾˣԼִ if Ĵˣ

  5. һǸֵصĶֵ exposedObjectȻ󷵻 exposedObjectշصĶΪ service1 Ĵ

һservice1 ĴҲȡˡ

6.2 ص DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>)

һIJһЩ棬Ͳٷˣ 5 ṹе£

singletonObjectsservice2<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 ж£

  1. service1

  2. service2

ԿsingletonObjects ߶Ǵ󣬱˴עģҲǴѭõ˽

4. ܽ

spring ѭķͽˣѭнĺǰ aopspring һ㣬 5 ṹ洢ҪϢһѭ⡣


ԭӣhttps://my.oschina.net/funcy/blog/4815992 ߸ˮƽд֮ӭָԭףҵתϵ߻Ȩҵתע