Spring getBean()方法执行过程
作者:bin- 1.先从单例缓存中获取bean
- 2.单例缓存中不存在bean,那么就创建他
- 2.1首先检查是否有父beanFactory
- 2.2标记bean是否创建过,避免重复创建
- 2.3获取bean的定义信息
- 2.4创建单例bean
- 2.4.1 createBean 实例化bean
- 2.4.1 (bean实例化前)InstantiationAwareBeanPostProcessor 后置处理器
- 2.4.2 (bean实例化)doCreateBean真正的创建bean
- 2.4.3 (bean实例化)createBeanInstance创建bean实例
- 2.4.4 (bean实例化后)执行MergedBeanDefinitionPostProcessor后置处理器
- 2.5 (循环依赖)earlySingletonExposure提前暴露bean工厂
- 2.5.1 (循环依赖)SmartInstantiationAwareBeanPostProcessor提前执行
- 2.6 populateBean() 注入bean的属性
- 2.6.1 (注入bean属性前)hasInstantiationAwareBeanPostProcessors后置处理器
- 2.6.2 (注入bean属性)applyPropertyValues
- 2.7 initializeBean 初始化bean
- 2.7.1 (bean初始化之前)invokeAwareMethods方法执行
- 2.7.2 (bean初始化之前)postProcessBeforeInitialization 后置处理器
- 2.7.3 (bean初始化)invokeInitMethods,bean初始方法执行
- 2.7.4 (bean初始化之后)postProcessAfterInitialization后置处理器
- 2.8 registerDisposableBeanIfNecessary注册销毁方法
- 2.9 addSingleton添加单单例池中
- 2.x 完结撒花
通过对getBean方法对源码分析,我们可以清晰的理解bean的加载过程
本文将涵盖:
1.包括前后置处理器调用时机?
2.循环依赖如何解决的?
getBean实际上调用的是doGetBean方法
public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
doGetBean方法比较长,我们逐步来看
protected T doGetBean(final String name, @Nullable final Class requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { ....
1.先从单例缓存中获取bean
Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { .... bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); }
我们查看getSingleton()方法,从DefaultSingletonBeanRegistry.singletonObjects属性中获取单例的bean对象
protected Object getSingleton(String beanName, boolean allowEarlyReference) { Object singletonObject = this.singletonObjects.get(beanName); .... return singletonObject; }
这里的singletonObjects其实就是我们通常指的单例池
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry { //单例缓存池 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
接着我们查看getObjectForBeanInstance()方法
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) { //如果beanInstance不是继承自FactoryBean //或者beanName是以(FACTORY_BEAN_PREFIX = "&")字符开头的,表示取beanFactory对象 //就直接返回当前bean if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } .... //如果是FactoryBean,那么就通过FactoryBean获取具体的bean对象 object = getObjectFromFactoryBean(factory, beanName, !synthetic); return object; }
2.单例缓存中不存在bean,那么就创建他
2.1首先检查是否有父beanFactory
首先检查是否有父beanFactory,那么用父beanFactory去加载
// 如何有父beanFactory,那么用父beanFactory去加载 //(这里通常没有) BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { .... }
2.2标记bean是否创建过,避免重复创建
//标记bean是否创建过,避免重复创建 if (!typeCheckOnly) { markBeanAsCreated(beanName); }
markBeanAsCreated内部加锁
protected void markBeanAsCreated(String beanName) { if (!this.alreadyCreated.contains(beanName)) { //加锁 synchronized (this.mergedBeanDefinitions) { if (!this.alreadyCreated.contains(beanName)) { clearMergedBeanDefinition(beanName); //添加创建状态 this.alreadyCreated.add(beanName); } } } }
2.3获取bean的定义信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args);
通过bean的定义信息,获取当前bean的依赖,即@DependsOn注解标注依赖的bean,如果存在,即先加载他
// 获取当前bean的依赖,即@DependsOn注解标注依赖的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { .... //也是调用getBean去获取这个bean getBean(dep); .... } }
2.4创建单例bean
将bean名称与一个ObjectFactory工厂传入,这里使用了Lambda的函数式接口,将行为()->{} 传入
的实际上是对ObjectFactory.getObject()的实现,实际上调用的是createBean方法去创建bean
// 创建单例bean if (mbd.isSingleton()) { //将bean名称与一个ObjectFactory工厂传入 //这里使用了Lambda的函数式接口 //()->{} 是对ObjectFactory.getObject()的实现 sharedInstance = getSingleton(beanName, () -> { .... return createBean(beanName, mbd, args); .... }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
2.4.1 createBean 实例化bean
createBean比较长,我们逐步来看
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
2.4.1 (bean实例化前)InstantiationAwareBeanPostProcessor 后置处理器
提供一个扩展,在bean实例创建前,让bean直接返回,不走后面其他的加载流程,通过实现InstantiationAwareBeanPostProcessor.class接口来做
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
如果实现InstantiationAwareBeanPostProcessor接口,就调用他的postProcessBeforeInstantiation方法,如果返回对象,就接着调用beanPostprocess.postProcessBeforeInstantiation处理这个bean,
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { .... if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } .... return bean; }
所以我们可以通过实现InstantiationAwareBeanPostProcessor.class接口,来根据情况自定义加载bean的过程,不走spring后续的过程
2.4.2 (bean实例化)doCreateBean真正的创建bean
正常情况下,我们都是走bean的加载bean过程即走到doCreateBean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
doCreateBean方法也比较长,我们逐步来看
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { .... instanceWrapper = createBeanInstance(beanName, mbd, args); ....
2.4.3 (bean实例化)createBeanInstance创建bean实例
我们通过instantiateUsingFactoryMethod方法返回了bean的实例对象
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { .... if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } ....
2.4.4 (bean实例化后)执行MergedBeanDefinitionPostProcessor后置处理器
在bean创建实例对象以后,调用实现了MergedBeanDefinitionPostProcessor.class接口的后置处理器
synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } }
2.5 (循环依赖)earlySingletonExposure提前暴露bean工厂
开启了循环依赖支持的化,就会添加一个bean工厂到三级缓存中
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { //开启了循环依赖支持的化,就会添加一个bean工厂到三级缓存中 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); }
这里加到三级缓存中,目的是为了解决循环依赖问题,那么在AbstractBeanFactory.doGeBean中的DefaultSingletonBeanRegistry.getSingleton中每次都会尝试会从三级缓存中获取一个bean,
如果出现循环依赖,那么就会触发调用singletonFactory.getObject()方法,这里又是一个lambda表达式
即执行的是() -> getEarlyBeanReference(beanName, mbd, bean)
protected Object getSingleton(String beanName, boolean allowEarlyReference) { .... ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //调用getObject()获取对象 singletonObject = singletonFactory.getObject(); } .... return singletonObject; }
2.5.1 (循环依赖)SmartInstantiationAwareBeanPostProcessor提前执行
如果出现循环依赖,那么在调用getEarlyBeanReference方法时,会提前执行SmartInstantiationAwareBeanPostProcessor后置处理器的
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) { SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp; exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName); } } } return exposedObject; }
查看实现接口SmartInstantiationAwareBeanPostProcessor.class.getEarlyBeanReference()的类有3个,但是实际有作用的只有
AbstractAutoProxyCreator.getEarlyBeanReference()方法,他的作用是去完成代理工作,并且内部使用advisedBeans的Map来记录哪些bean被代理过了,避免重复代理工作
public Object getEarlyBeanReference(Object bean, String beanName) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { this.earlyProxyReferences.add(cacheKey); } //如果需要代理,就完成代理工作 return wrapIfNecessary(bean, beanName, cacheKey); }
2.6 populateBean() 注入bean的属性
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
populateBean()的代码也比较多,我们逐个来看
2.6.1 (注入bean属性前)hasInstantiationAwareBeanPostProcessors后置处理器
属性注入前,先执行hasInstantiationAwareBeanPostProcessors.postProcessAfterInstantiation()方法,
如果该方法返回false,那么就不会执行属性的赋值了,直接return
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; }
然后还是在注入前,再执行InstantiationAwareBeanPostProcessor.postProcessPropertyValues()对属性进行赋值
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { .... pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); .... } } }
但是我们看实现postProcessPropertyValues的方法,发部分都标注了@Deprecated,表示spring不使用这种方式进行属性的赋值,但是还是留了一个入口给我们自定义属性赋值的方式
@Deprecated @Override public PropertyValues postProcessPropertyValues(
2.6.2 (注入bean属性)applyPropertyValues
applyPropertyValues方法才是真正的对属性进行赋值,其内部就是使用反射去设置熟悉的值,这里不展开来看了
if (pvs != null) { applyPropertyValues(beanName, mbd, bw, pvs); }
2.7 initializeBean 初始化bean
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { //执行BeanNameAware、BeanClassLoaderAware、BeanFactoryAware invokeAwareMethods(beanName, bean); //执行postProcessBeforeInitialization wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); //执行@PostConsuct等方式标注的初始化方法 invokeInitMethods(beanName, wrappedBean, mbd); //执行postProcessAfterInitialization wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); }
2.7.1 (bean初始化之前)invokeAwareMethods方法执行
实现了BeanNameAware、BeanClassLoaderAware、BeanFactoryAware接口的方法,会进行回调
private void invokeAwareMethods(final String beanName, final Object bean) { .... ((BeanNameAware) bean).setBeanName(beanName); ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); .... } }
2.7.2 (bean初始化之前)postProcessBeforeInitialization 后置处理器
bean初始化之前执行BeanPostProcessor.postProcessBeforeInitialization后置处理器的回调
public Object applyBeanPostProcessorsBeforeInitialization( Object existingBean, String beanName) throws BeansException { for (BeanPostProcessor processor : getBeanPostProcessors()) { Object current = processor.postProcessBeforeInitialization(result, beanName); .... } }
2.7.3 (bean初始化)invokeInitMethods,bean初始方法执行
执行我们自定义的初始化方法,相当于回调初始化方法
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd) throws Throwable {
2.7.4 (bean初始化之后)postProcessAfterInitialization后置处理器
bean初始化之后执行BeanPostProcessor.postProcessAfterInitialization后置处理器的回调
@Override public Object applyBeanPostProcessorsAfterInitialization (Object existingBean, String beanName) throws BeansException { .... Object current = processor.postProcessAfterInitialization(result, beanName); .... }
2.8 registerDisposableBeanIfNecessary注册销毁方法
将@PreDestroy注解的方法进行注册,在容器关闭时回调该方法
registerDisposableBeanIfNecessary(beanName, bean, mbd);
2.9 addSingleton添加单单例池中
通过DefaultSingletonBeanRegistry.getSingleton处理结束后,判断是否是新的单例,如果是的话,就加入单例池中去
if (newSingleton) { addSingleton(beanName, singletonObject); } protected void addSingleton(String beanName, Object singletonObject) { synchronized (this.singletonObjects) { this.singletonObjects.put(beanName, singletonObject); } }
2.x 完结撒花
return exposedObject;