随着我们代码中更多服务的出现与依赖关系的耦合,bean与bean之间的交互往往会涉及很多对其他类的依赖。我们通常用简单的Autowired、提供对应依赖对象的setter方法以及构造器中传入需要引用的其他对象,spring就可以完美的做好依赖关系自动装配。那么本节就来分析下spring中是如何完成bean之间这些依赖的自动查找与注入
关于这个话题,最重要的是spring中用到的三级缓存。但spring中的循环依赖情况分很多种,本文会进行不同场景的依次分析。
一级缓存:singletonObjects (存放的是已经完成整个生命周期初始化的对象,是正常getBean方式拿出来的源头)
/** Cache of singleton objects: bean name to bean instance. */
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
二级缓存:earlySingletonObjects (暂时放的是通过各种方式实例化出来的对象,属性及初始化方法及后置处理等过程还未进行)
/** Cache of early singleton objects: bean name to bean instance. */
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
三级缓存:singletonFactories (允许提前暴露引用下用于创建bean的工厂,在代码体现上是一个lamda方法:()->createBean(beanName, mbd, args))
/** Cache of singleton factories: bean name to ObjectFactory. */
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
单例与单例setter依赖
在spring中,创建的bean如果不指定scope一般默认为单例的。注解依赖方式包括字段级别注解及方法级别注解两种情况,常见A,B依赖代码如下
Bean1:
@Component
public class BeanSetter1 {
@Autowired
private BeanSetter2 beanSetter2;
public void print(){
System.out.println("autowired beanSetter2:"+beanSetter2);
}
//@Autowired
// public void setBeanSetter2(BeanSetter2 beanSetter2) {
// this.beanSetter2 = beanSetter2;
// }
//}
Bean2:
@Component
public class BeanSetter2 {
@Autowired
private BeanSetter1 beanSetter1;
public void print(){
System.out.println("autowired beanSetter1:"+beanSetter1);
}
// @Autowired
// public void setBeanSetter1(BeanSetter1 beanSetter1){
// this.beanSetter1 = beanSetter1;
// }
}
启动容器,通过context拿到对应的bean以及其中注入的依赖。其中BeanSetter1与BeanSetter2中的属性都与容器中各自对应的beanSetter是同一个单例对象
对于singleton类型的bean,spring在创建context时会完成对该bean的实例化、初始化、后置处理等一系列过程。在refresh中的finishBeanFactoryInitialization中就是负责对所有满足条件的bean
进行预先创建及缓存过程。
判断条件如下: 非抽象、单例、非懒加载。对FactoryBean还需要满足允许提早初始化
在上面流程中,当beanName为beanSetter1时,getBean() 开始进行BeanSetter1的创建及初始化
缓存获取
第一次从singletonObjects缓存中拿,同时允许查找提前引用缓存allowEarlyReference->singletonFactories
DefaultSingletonBeanRegistry
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
可惜现在bean才开始创建并不在缓存中也还未设置开始创建等状态,所以拿出来为空直接返回。接着为创建该bean做一些bd的清除及状态设定
markBeanAsCreated
clearMergedBeanDefinition(beanName)
this.alreadyCreated.add(beanName);
按照bean的scope类型进行不同方式的创建
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
...
return createBean(beanName, mbd, args);
...
);
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
创建bean的开始
在getSingleton中,第二次尝试从singletonObjects中拿依然为空,此时经过bean创建前期的一系列检验及状态的标记后调用ObjectFactory进行bean的真正创建即createBean(beanName, mbd, args)
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (this.singletonsCurrentlyInDestruction) {
throw new BeanCreationNotAllowedException...
}
//检验当前bean是否可以创建的:不在inCreationCheckExclusions名单中且成功加入singletonsCurrentlyInCreation中的。(在ConfigurationClassEnhancer中会通过setCurrentlyInCreation对该两种名单设置)
beforeSingletonCreation(beanName);
boolean newSingleton = false;
try {
//真正完成bean创建、初始化、后置处理及代理替换的入口
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
catch (IllegalStateException ex) {
...
}
catch (BeanCreationException ex) {
...
}
finally {
...
//不在inCreationCheckExclusions名单中并从在创建bean名单中移除
afterSingletonCreation(beanName);
}
if (newSingleton) {
//将完成所有过程的bean放置到一级缓存singletonObjects,并从其他缓存中移除
addSingleton(beanName, singletonObject);
}
}
return singletonObject;
}
对于objectFactory创建bean的过程进行分析,
AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args){
//1.解析beanClass,找到需要创建的类型是什么
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
//2.进行方法override方法的查找与设置
mbdToUse.prepareMethodOverrides();
//3.调用当前容器中是否有后置处理器InstantiationAwareBeanPostProcessor的applyBeanPostProcessorsBeforeInstantiation能提前得到对象(并一起完成applyBeanPostProcessorsAfterInitialization)提前结束,一般用于给使用者通过配置或者自定义获得一个代理对象(大部分情况都是null)
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
//4. 进行具体创建bean的流程处理
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
return beanInstance
接下来分析doCreateBean的实现过程
AbstractAutowireCapableBeanFactory
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//1.从factoryBeanMethodCache中拿或者创建一个,主要是factoryBean情况下
BeanWrapper instanceWrapper = this.factoryBeanInstanceCache.remove(beanName)
or
//其中允许提供自定义构造方式obtainFromSupplier、factoryMethodName实例化,构造参数注入及默认实例化等方式直接创建。
//在@Configuration中使用@Bean方式下定义的bean创建可以用factor