您的位置:首页 > 编程语言 > Java开发

Spring源码解析之Bean创建的核心步骤,三级缓存解决循环依赖的原理分析

2020-07-15 04:26 651 查看

BeanFactory体系


先来一张图压压惊,由上图可见DefaultListableBeanFactory为集大成者,实现了所有接口,具备容器的基本功能,所以下文中提到的bean容器都指的是DefaultListableBeanFactory。下面对BeanFactory接口的继承体系简单进行介绍。

BeanFactory

bean 容器的顶级接口,该接口定义了容器提供的基本功能。

  • ​ getBean(String beanName)—>根据名称获取bean
  • ​ getBean(Class classType)—>根据类型获取bean
  • ​ isSingleton(String beanName)—>是否为单例
  • ​ isPrototype(String beanName)—>是否为原型
  • ​ …

注意:此处只提供了获取单个bean实例的功能

BeanFactory的直接子接口:HierarchicalBeanFactory,ListableBeanFactory,AutowireCapableBeanFactory

HierarchicalBeanFactory
具备分层能力的工厂,主要增加getParentBeanFactory()方法,所谓的父子容器
ListableBeanFactory
具备获取多个bean实例功能的工厂 ,主要增加
String [] getBeanNamesForType(Class<T> classType)--->获取bean容器中指定类型的bean名称集合,所谓面向接口,所以可能存在多个实现类的实例
Map<String,T> getBeanOfType(Class<T> classType)--->获取bean容器中指定类型的bean实例集合
...等相关方法
AutowireCapableBeanFactory
具备装备能力的工厂,增加autowireBean(),createBean(Class<T> classType)...等相关方法

惊叹Spring各大继承体系的庞大复杂之余,初写博客真的是一件很难的事情,还是不继续往下介绍了(主要是因为自己还没有完全体会够),所以直接撸源码吧

IOC源码解析

前置知识:主要是为了扫个盲,已了解的可以直接略过

spring容器中一个正常的完整的单例bean的创建都要经过哪些关键步骤?

1.1 实例化 Instantiation

~Supplier接口
正常情况下我们不会自己使用,都是框架内部使用的,偶然在看Mybatis源码的时候瞥见过一眼,可参考lambda Supplier函数式接口,理解为一个提供者
~静态工厂方法和工厂实例方法  @Bean注解的方法会走这里哦
~有参构造
~无参构造
主要是通过反射调用默认构造函数创建bean实例,此时bean的属性都还是默认值null或基本数据类型的初始值,调用有参构造函数执行过相应填充逻辑(假设有)的另当别论

1.2 属性填充 Population

注入属性,所谓DI(依赖注入),@Value @Autowired @Resource等

1.3 初始化 Initialization

执行指定的初始化方法,完成自定义的初始化工作
此处会按顺序完成如下操作:
invokeAwareMethods,
postProcessBeforeInitialization,  @PreConstruct注解在此处被处理
afterPropertiesSet,   当前Bean实现InitializingBean接口时
init-method,
postProcessAfterInitialization    AOP创建代理对象的入口之一
注:@PreConstruct会被CommonAnnotationBeanPostProcessor--->InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization方法处理
所谓spring中的三级缓存到底是个什么东西?

2.1

Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256)
—>一级缓存

​ 存放的是已经完成实例化属性填充初始化步骤的单例bean实例

2.2

Map<String, Object> earlySingletonObjects = new HashMap<>(16)
—>二级缓存

​ 存放的是提前暴露的单例bean实例,可能是代理对象,也可能是未经代理的原对象,但都还没有完成初始化的步骤

2.3

Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16)
—>三级缓存

​ 存放的是ObjectFactory的匿名内部类实例,一个获取提前暴露的单例bean引用的回调

getEarlyBeanReference()
此处画重点,因为可以在这里进行代理对象的创建,也即AOP切面的织入

事先声明:此处仅就第一次创建单例bean的完整流程进行分析,不考虑bean已经在容器一级缓存(bean已经完全创建好了)中的情况

入口:AbstractBeanFactory#getBean

此抽象类实现了getBean(String beanName),内部调用doGetBean(final String name, @Nullable final Class requiredType,@Nullable final Object[] args, boolean typeCheckOnly),该方法的主要处理流程如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
Object bean; // 最终要返回的bean
1.final String beanName transformedBeanName(name)
2.Object sharedInstance = DefaultSingletonBeanRegistry#getSingleton(beanName);
if sharedInstance != null // 不为空,即指定beanName已完成bean的创建过程
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null)
3.isPrototypeCurrentlyInCreation(beanName)//如果原型bean发生循环依赖则直接抛异常
4.BeanFactory parentBeanFactory = getParentBeanFactory();
if parentBeanFactory != null && !containsBeanDefinition(beanName)
//父容器不为空且当前容器中不存在beanName对应bean定义信息时尝试从父容器中获取bean,又是一轮AbstractBeanFactory#getBean的调用流程,此处忽略
5.markBeanAsCreated(beanName); //标记beanName到alreadyCreated集合中
6.final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
7.checkMergedBeanDefinition(mbd, beanName, args);//判断是否为抽象类,是则直接抛异常
8.String[] dependsOn = mbd.getDependsOn();
if dependsOn != null
// 处理@DependsOn 的情况,循环调用getBean(dep)所depends on的bean,此处忽略
9.if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
});
10.bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
11.T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType) 		           if convertedBean != null // 不为空
return convertedBean;
12. return <T> bean
}
}

非重要步骤已在伪代码中注释,其他重要步骤解释如下:

  • <1>获取原始bean名称 此处主要完成两个工作 去掉name的前缀"&"
  • 从aliasMap中获取bean的原始名称 解决aliasA—>aliasB—>ABean多重别名的情况
  • <2>尝试从一级缓存中获取bean实例,此处链接到
    DefaultSingletonBeanRegistry#getSingleton(beanName)
  • <4>父容器不为空且当前容器中不存在beanName对应bean定义信息时尝试从父容器中获取bean,又是一轮AbstractBeanFactory#getBean的调用流程,此处忽略
  • <6>从父类中合并BeanDefinition信息,主要处理方法覆盖等,此处尚未具体深入了解
  • <9>创建bean实例,此处链接到
    DefaultSingletonBeanRegistry#getSingleton(beanName,objectFactory)
    方法,传递一个ObjectFactory的匿名内部类实例,通过回调getObject()方法触发
    AbstractAutowireCapableBeanFactory#createBean(String beanName, RootBeanDefinition mbd, Object[] args)
    的执行
  • <10>判断
    createBean()
    返回的实例sharedInstance
      sharedInstance instanceOf FactoryBean name 包含 & 前缀 直接返回FactoryBean对象 sharedInstance
    • name 不包含 & 前缀 调用sharedInstance.getObject()方法返回真正的bean
  • !(sharedInstance instanceOf FactoryBean) 直接返回 sharedInstance
  • <11,12>进行必要的类型转换
  • DefaultSingletonBeanRegistry#getSingleton

    此处从被调用的顺序分别介绍一下getSingleton的三个重载方法

    原始接口方法
    getSingleton(String beanName)
    public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // 原始接口方法
    @Override
    @Nullable
    public Object getSingleton(String beanName) {
    return getSingleton(beanName, true);
    }
    }

    实现SingletonBeanRegistry接口的方法,此处内部调用重载方法一allowEarlyReference参数为true,该方法在

    AbstractBeanFactory#doCreateBean
    的开始地方较早的被调用

    重载方法一
    getSingleton(String beanName, boolean allowEarlyReference)
    public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // 重载方法一
    @Nullable
    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    // 从一级缓存中获取单例对象
    Object singletonObject = this.singletonObjects.get(beanName);
    // isSingletonCurrentlyInCreation:判断当前beanName是否在singletonsCurrentlyInCreation集合中
    if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    synchronized (this.singletonObjects) {
    // 尝试从二级缓存中获取提前暴露的单例bean引用,getEarlyBeanReference被提前调用过时才会存在
    singletonObject = this.earlySingletonObjects.get(beanName);
    // allowEarlyReference 是否允许从三级缓存中的ObjectFactory#getObject拿到对象
    if (singletonObject == null && allowEarlyReference) {
    // 从三级缓存中获取
    ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    if (singletonFactory != null) {
    // 回调ObjectFactory#getObject方法获取提前暴露的引用,也即触发AbstractAutowireCapableBeanFactory#getEarlyBeanReference执行
    singletonObject = singletonFactory.getObject();
    // 从三级缓存移动到了二级缓存
    this.earlySingletonObjects.put(beanName, singletonObject);
    // 同时移除三级缓存
    this.singletonFactories.remove(beanName);
    }
    }
    }
    }
    return singletonObject;
    }
    }

    该重载方法主要被两个地方调用,两次调用所传递的allowEarlyReference不同,所以两处调用所代表的含义也有所不同

    • 第一次调用:调用链(只列出了关键方法执行链),传入allowEarlyReference为true

      AbstractBeanFactory
      --->#getBean
      --->#doGetBean
      --->DefaultSingletonBeanRegistry#getSingleton(beanName)
      --->#getSingleton(beanName,true)

    ​ 此处就是否存在循环依赖两种情况进行分析

    1. 不存在循环依赖:此种情况比较简单,因为在一开始较早的时候调用此方法,指定beanName并未出现在singletonsCurrentlyInCreation集合中,所以如果一级缓存中不存在时直接放回null

    2. 存在循环依赖:假设A->B,B->A,并先创建A 注意两者同时构造器依赖的时候,spring是无法解决这种循环依赖的,会报错,因为放入三级缓存的前提是Bean完成了实例化,而循环依赖的解决关键是三级缓存,当然二级缓存也是有它存在原因的。

      ​ 第一次调用getBean(A)创建A,然后进入到该方法

    ​ 1.同一beanName A/B第一次进入此方法时直接返回null,第二次进入时则不是直接返回null了

    ​ 2. 进行beanName A/B 的实例化过程,实例化之前会将beanName A/B 放置到singletonsCurrentlyInCreation集合中

    ​ 2.1若beanName A/B 不是构造器依赖beanName B/A ,则在A/B完成实例化操作之后,此处有一个关键操作,会将实例化之后的bean提前暴露,通过新建ObjectFactory接口的匿名内部类实例(该实例的getObject回调方法,会触发getEarlyBeanReference的执行,返回提前暴露的bean,Aop在此处可以进行增强),添加进三级缓存中,然后进行属性填充时发现依赖B/A

    ​ 2.2若A/B构造器依赖B/A,则在A/B实例化时发现依赖B/A, 注意此时三级缓存中并不存在提前暴露的 bean A/B,所以这种情况下必须强制让B/A在A/B之前调用getBean(beanName)方法,否则依旧会存在问题,不知道spring对于这种情况会不会提前预知来调整Bean的创建顺序,暂时不清楚,欢迎指点

    ​ 第二次调用getBean(B)创建B,重复执行以上步骤

    ​ 3.所以到这里为止,A,B分别进行了上述步骤,当第三次调用getBean(A)创建A,也即B属性填充A时,因为A和B都执行了上述步骤,所以A,B都已经存在singletonsCurrentlyInCreation集合中,于是在1步骤并不会立马直接返回,而是从三级缓存中获取到了ObjectFactory接口的匿名内部类实例,并调用其getObject()方法触发getEarlyBeanReference返回了提前暴露的bean引用,然后将引用放置到二级缓存,同时移除相应的三级缓存.

    ​ 4.于是B顺利的完成了属性填充及初始化工作返回,最后A也成功获取到依赖B,完成后续的初始化工作,然后完美的解决了循环依赖的问题。

    • 第二次调用:调用链为(只列出了关键方法执行链),传入allowEarlyReference为false

      AbstractBeanFactory
      --->getBean
      --->doGetBean
      --->DefaultSingletonBeanRegistry
      --->getSingleton(beanName)
      --->getSingleton(beanName,true)
      --->getSingleton(beanName,objectFactory)
      --->objectFactory.getObject()
      --->AbstractAutowireCapableBeanFactory
      --->createBean
      --->doCreateBean
      --->createBeanInstance
      --->populateBean
      --->initializeBean
      --->getSingleton(beanName,false)

      也即在bean完成了实例化,属性填充,初始化之后调用。如果指定的beanName存在循环依赖,而且被执行了getEarlyBeanReference将提前暴露的bean从三级缓存移到了二级缓存,那么此处返回的bean就不为空,后面对此处的作用做了分析。

    重载方法二
    getSingleton(String beanName, ObjectFactory<?> singletonFactory)
    public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // 重载方法二
    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
    Object singletonObject = this.singletonObjects.get(beanName);
    if (singletonObject == null) {
    // ... 省略
    // 将当前beanName放到singletonsCurrentlyInCreation集合中
    beforeSingletonCreation(beanName);
    boolean newSingleton = false;
    // ... 省略
    try {
    // 调用匿名内部类获取单例对象,触发AbstractAutowireCapableBeanFactory#createBean方法的执行,createBean方法的执行会完成实例化,属性填充,初始化的工作
    singletonObject = singletonFactory.getObject();
    newSingleton = true;
    }
    catch (IllegalStateException ex) {
    // ... 省略
    }
    catch (BeanCreationException ex) {
    // ... 省略
    }
    finally {
    // 将当前beanName从singletonsCurrentlyInCreation集合中移除
    afterSingletonCreation(beanName);
    }
    // 将产生的单例Bean放入一级缓存中,同时移除二,三级缓存
    if (newSingleton) {
    addSingleton(beanName, singletonObject);
    }
    }
    return singletonObject;
    }
    }
    }

    当在第一次调用原始接口方法getSingleton(String beanName)返回null时,会调用该方法,传入一个ObjectFactory接口的匿名内部类实例,该方法主要做四件事情:

    1. 将当前beanName放到

      singletonsCurrentlyInCreation
      集合中

    2. 调用匿名内部类实例对象的getObject()方法触发AbstractAutowireCapableBeanFactory#createBean方法的执行,createBean方法的执行会完成实例化,属性填充,初始化的工作

    3. 将当前beanName从

      singletonsCurrentlyInCreation
      集合中移除

    4. 将产生的单例Bean放入一级缓存中,同时移除二,三级缓存

    AbstractAutowireCapableBeanFactory#createBean
    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    implements AutowireCapableBeanFactory {
    
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    throws BeanCreationException {
    RootBeanDefinition mbdToUse = mbd;
    1.Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    2.mbdToUse.prepareMethodOverrides();
    // 创建代理对象的入口之一,但此处的条件比较严苛,正常bean的创建流程一般不会走这里
    3.Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    if (bean != null) {
    return bean;
    }
    // 完成Bean实例的创建(实例化、填充属性、初始化)
    4.Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    return beanInstance;
    }
    }
    AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation
    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    implements AutowireCapableBeanFactory {
    // AOP进行切面织入的另一个特殊入口,要求beanName的实例已经在beanFactory中创建完成,且存在自定义的TargetSourceCreator接口的实现类
    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    // Make sure bean class is actually resolved at this point.
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    Class<?> targetType = determineTargetType(beanName, mbd);
    if (targetType != null) {
    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    if (bean != null) {
    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }
    }
    }
    mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
    }
    }
    AbstractAutowireCapableBeanFactory#doCreateBean
    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    implements AutowireCapableBeanFactory {
    /**
    * 真正创建Bean的地方
    * @param beanName
    * @param mbd
    * @param args
    * @return
    * @throws BeanCreationException
    */
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
    throws BeanCreationException {
    
    // Instantiate the bean.
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
    instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    // bean初始化第一步:默认调用无参构造实例化Bean
    // 构造参数依赖注入,就是发生在这一步
    if (instanceWrapper == null) {
    instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 实例化后的Bean对象
    final Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
    mbd.resolvedTargetType = beanType;
    }
    // ...
    // Eagerly cache singletons to be able to resolve circular references
    // even when triggered by lifecycle interfaces like BeanFactoryAware.
    // 解决循环依赖的关键步骤
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
    isSingletonCurrentlyInCreation(beanName));
    // 如果需要提前暴露单例Bean,则将该Bean放入三级缓存中 默认为true
    if (earlySingletonExposure) {
    // ...
    // 将刚创建的bean放入三级缓存中singleFactories(key是beanName,value是ObjectFactory)
    addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
    // bean创建第二步:填充属性(DI依赖注入发生在此步骤)
    populateBean(beanName, mbd, instanceWrapper);
    // bean创建第三步:调用初始化方法,完成bean的初始化操作(AOP的第三个入口)
    // AOP是通过自动代理创建器AbstractAutoProxyCreator的postProcessAfterInitialization()方法的执行进行代理对象的创建的,AbstractAutoProxyCreator是BeanPostProcessor接口的实现
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
    // ...
    }
    //  此处要画一个重点,我刚开始看这里的时候忽略掉了
    if (earlySingletonExposure) {
    Object earlySingletonReference = getSingleton(beanName, false);
    // 如果从二级缓存中获取到的经getEarlyBeanReference()处理之后的earlySingletonReference不为空,则该earlySingletonReference可能为代理对象,也可能为原始对象
    if (earlySingletonReference != null) {
    // 因为在初始化时后置处理器的postProcessAfterInitialization()方法处理可能创建代理对象,也可能不创建代理对象,不创建代理对象的原因有两种,1.bean本身不需要被代理,2.已经在earlySingletonReference中被代理并添加到earlyProxyReferences中,此时会跳过代理直接返回原始对象
    // 此处如果经过初始化后置处理器处理后返回的bean与原始bean相等时,则说明postProcessAfterInitialization(后置处理时)中未创建代理
    if (exposedObject == bean) {
    // 不管初始化后置处理器是因为跳过代理还是本身不需要代理,都将earlySingletonReference赋值给exposedObject
    // 跳过代理时earlySingletonReference本身就是代理对象
    // 本身不需要代理时 三者earlySingletonReference,exposedObject,bean都是原对象,不影响
    // 所以此处的关键点在于避免postProcessAfterInitialization()因跳过代理而导致将原始对象返回的情况出现,所以这也就是二级缓存出现的意义,提前将可能的代理对象放置到二级缓存
    exposedObject = earlySingletonReference;
    }
    else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
    // allowRawInjectionDespiteWrapping默认为false,此时若有对象已经依赖了当前对象,比如循环依赖时从getEarlyBeanReference()提前获取当前对象(此时的当前对象肯定是原对象)进行依赖注入,因为exposedObject != bean说明postProcessAfterInitialization()返回的是代理对象
    String[] dependentBeans = getDependentBeans(beanName);
    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
    for (String dependentBean : dependentBeans) {
    // 如果依赖了当前对象A的对象B发现依赖的对象A是原始对象,则报错,因为容器中真正准备放的是代理对象A    @Async注解存在循环依赖且使用不当的时候可能会报这个错误,因为此种方式代理对象的创建是通过postProcessAfterInitialization()完成的,在getEarlyBeanReference()不会对代理对象进行创建
    if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
    actualDependentBeans.add(dependentBean);
    }
    }
    if (!actualDependentBeans.isEmpty()) {
    throw new BeanCurrentlyInCreationException(beanName,
    "Bean with name '" + beanName + "' has been injected into other beans [" +
    StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
    "] in its raw version as part of a circular reference, but has eventually been " +
    "wrapped. This means that said other beans do not use the final version of the " +
    "bean. This is often the result of over-eager type matching - consider using " +
    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
    }
    }
    }
    }
    // ...
    return exposedObject;
    }
    }
    AbstractAutowireCapableBeanFactory#getEarlyBeanReference
    public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
    implements AutowireCapableBeanFactory {
    
    protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
    Object exposedObject = bean;
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
    if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
    // AOP创建代理对象的第二个入口 默认由AbstractAutoProxyCreator创建
    exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
    }
    }
    }
    return exposedObject;
    }
    }

    AOP创建代理对象的三个入口

    此处直接过渡到AOP的部分源码中,窥探一眼AOP代理创建的入口方法,按照顺序来,就一眼哈哈,多了顶不住

    AbstractAutoProxyCreator#postProcessBeforeInstantiation

    该方法较早的被调用,在

    AbstractAutowireCapableBeanFactory#createBean
    方法中触发调用,但在
    AbstractAutowireCapableBeanFactory#doCreateBean
    方法之前,也即实例化之前的调用

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
    Object cacheKey = getCacheKey(beanClass, beanName);
    // 已经被通知或者已经被customTargetSourceCreators创建过时直接返回null
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
    if (this.advisedBeans.containsKey(cacheKey)) {
    return null;
    }
    // 是基础设施接口Advice.class,Pointcut.class,Advisor,AopInfrastructureBean.class的字类或者应该被跳过时直接返回null
    if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return null;
    }
    }
    // Create proxy here if we have a custom TargetSource.
    // Suppresses unnecessary default instantiation of the target bean:
    // The TargetSource will handle target instances in a custom fashion.
    /**
    * 此处要求beanFactory非空,自定义的customTargetSourceCreators(即自定义TargetSourceCreator的实现类)非空,而且beanFactory已经存在该bean时
    * 所以正常创建bean的时候是不会在此处创建代理对象的
    */
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
    if (StringUtils.hasLength(beanName)) {
    this.targetSourcedBeans.add(beanName);
    }
    // 获取拦截器们,下沉到具体子类实现
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
    // 创建代理对象
    Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
    }
    return null;
    }
    }
    AbstractAutoProxyCreator#getEarlyBeanReference

    该方法一般在出现循环依赖的情况下由依赖当前对象的其他对象调用,由

    DefaultSingletonBeanRegistry#getSingleton(beanName,true)
    调用触发,从三级缓存获取到提前暴露引用的回调实例
    objectFactory
    ,并调用该
    objectFactory#getObject()
    触发此方法的执行。

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    @Override
    public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
    // 先获取beanName,主要是为FactoryBean类型添加&前缀
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    // 判断是否已经在earlyProxyReferences集合中,不在则添加进去
    if (!this.earlyProxyReferences.contains(cacheKey)) {
    this.earlyProxyReferences.add(cacheKey);
    }
    // 创建代理对象,如果必要的话
    return wrapIfNecessary(bean, beanName, cacheKey);
    }
    /**
    * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
    * @param bean the raw bean instance
    * @param beanName the name of the bean
    * @param cacheKey the cache key for metadata access
    * @return a proxy wrapping the bean, or the raw bean instance as-is
    */
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 前面先做一些基本的判断
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    return bean;
    }
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    return bean;
    }
    // Advice/Pointcut/Advisor/AopInfrastructureBean接口的beanClass不进行代理以及对beanName为aop内的切面名也不进行代理
    // 此处可查看子类复写的shouldSkip()方法
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
    }
    // Create proxy if we have advice.
    // 查找对代理类相关的advisor对象集合,此处就与point-cut表达式有关了
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 对相应的advisor不为空才采取代理
    if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    // 通过jdk动态代理或者cglib动态代理,产生代理对象,这里传入的是SingletonTargetSource对象喔,对原始bean对象进行了包装
    Object proxy = createProxy(
    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    // 放入代理类型缓存
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
    }
    // 放入通知缓存
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
    }
    }
    AbstractAutoProxyCreator#postProcessAfterInitialization

    该方法的调用则发生在实例化

    Instantiation
    ,属性填充
    Population
    之后,初始化
    Initialization
    方法调用时被执行

    public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
    implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    /**
    * Create a proxy with the configured interceptors if the bean is
    * identified as one to proxy by the subclass.
    * @see #getAdvicesAndAdvisorsForBean
    */
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
    // 同getEarlyBeanReference开始处,解析beanName
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    // 判断earlyProxyReferences是否已存在,如果在getEarlyBeanReference执行过代理对象的创建过程的话,则直接跳过返回原始bean对象,以防创建两次
    if (!this.earlyProxyReferences.contains(cacheKey)) {
    // 使用动态代理技术,产生代理对象
    return wrapIfNecessary(bean, beanName, cacheKey);
    }
    }
    return bean;
    }
    }

    到这里深感疲惫,还有很多东西都来不及介绍,比如

    BeanPostProcessor
    的继承体系,比如
    createBeanInstance
    实例化bean的分析,比如
    populateBean
    依赖注入的分析,比如
    initializeBean
    初始化bean的分析,比如AOP创建代理对象的具体过程,所以给本文定一个核心就是单例bean的主要创建过程,以及循环依赖的解决过程,为什么需要三级缓存而不是二级缓存。

    最后引入一个骚接口:

    TargetSource是一个很骚的接口,AOP创建代理对象的时候,传递的是TargetSource的实现类,默认为

    SingletonTargetSource
    ,它持有真正的
    target
    对象的引用,在AOP拦截处理过程中,通过
    SingletonTargetSource
    对象实例的
    getTargetSource()
    获取真正的目标对象target,然后反射执行
    target
    目标对象的目标方法。不同的实现类可以控制
    target
    对象的返回逻辑,此处个人理解为一种更细粒度的控制,允许开发人员介入获取目标对象的过程,得到更好的扩展。

    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: