首页 > java > Spring getBean()方法执行过程

Spring getBean()方法执行过程

作者:bin
目录
[隐藏]

通过对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;

您必须 [ 登录 ] 才能发表留言!