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

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

先来一张图压压惊,由上图可见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;
						}
					});
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
    }
    10.T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType) 		           if convertedBean != null // 不为空
        		return convertedBean;
    11. 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>进行必要的类型转换

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
    --->#createBean
    	--->#doCreateBean
    		--->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
    --->createBean
    	--->doCreateBean
    --->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) {
             // 如果完成初始化之后的bean与提前暴露的bean相等时
            // 因为在初始化时后置处理器的postProcessAfterInitialization()方法处理可能创建代理对象,也可能不创建代理对象,不创建代理对象的原因有两种,1.bean本身不需要被代理,2.已经在earlySingletonReference中被代理并添加到earlyProxyReferences中,此时会跳过代理直接返回原始对象
            // 此处若相等,则说明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

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

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

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的主要创建过程,以及循环依赖的解决过程,为什么需要三级缓存而不是二级缓存。

最后引入一个骚接口:

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

TargetSource是一个很骚的接口,AOP创建代理对象的时候,传递的是TargetSource的实现类,默认为
SingletonTargetSource ,它持有真正的target对象的引用,在AOP拦截处理过程中,通过
SingletonTargetSource

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

原文 

https://juejin.im/post/5e9b26fe6fb9a03c7413841e

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » Spring源码-bean创建的核心步骤,三级缓存解决循环依赖的原理分析

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址