spring 源码解析(一) bean的生命周期

首先来一张bean的生命周期图

该篇文章将以加载类为起点开始分析bean的生命周期。首先不能完全保证理解正确,只是博主自己的思路,有问题及时指出,共同进步。

bean生命周期源码分析

加载类

源码将从AbstractAutowireCapableBeanFactory中的createBean方法开始分析,也就是合并完beanDefinition,开始加载类。

@Override
	protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
        ...
		RootBeanDefinition mbdToUse = mbd;

		// 确保bean类在这一点上得到了实际的解析
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
			mbdToUse.prepareMethodOverrides();
		}
		...

		try {
			// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if (bean != null) {
				return bean;
			}
		}
		...

		try {
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isTraceEnabled()) {
				logger.trace("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		...
	}

从以上源码可以看到调用了第一个resolveBeanClass,进入该方法查看。

//是否已经有了beanClass
if (mbd.hasBeanClass()) {
   return mbd.getBeanClass();
}
//安全管理器
if (System.getSecurityManager() != null) {
   return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() {
      @Override
      public Class<?> run() throws Exception {
         return doResolveBeanClass(mbd, typesToMatch);
      }
   }, getAccessControlContext());
}
else {
    //加载类,这里面就是类加载器加载类的逻辑了
   return doResolveBeanClass(mbd, typesToMatch);
}

实例化前

分析完resolveBeanClass方法后回到createBean方法中来,继续向下走,看这一段代码。

try {
   //给BeanPostProcessors一个返回代理而不是目标bean实例的机会
   Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
   //如果已经返回了对象,则不再执行spring的实例化流程,直接返回bean
   if (bean != null) {
      return bean;
   }
}

resolveBeforeInstantiation方法中有这样两个方法,bean通过InstantiationAwareBeanPostProcessor接口来实现两个影响实例化的方法,允许第三方可以不按照Spring的正常流程来创建一个Bean,利用InstantiationAwareBeanPostProcessor接口的方法来提前返回一个Bean对象,直接结束Bean的生命周期,从而达到干预bean实例化的过程。这就对应上一步 给BeanPostProcessors一个返回代理而不是目标bean实例的机会

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) {
//如果实例化前的时候返回了对象,说明不再使用spring提供的实例化流程,这时直接调用实例化后方法。
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

一个小demo

当对象是user时,会被实例化前处理器处理,生成一个order对象,然后直接结束bean的生命周期。

@Component
public class MyInstantiation implements InstantiationAwareBeanPostProcessor {
    //允许第三方可以不按照Spring的正常流程来创建一个Bean,
// 可以利用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法来提前返回一个Bean对象,
// 直接结束Bean的生命周期
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        System.out.println("被干预的beanName:"+beanName);
        if (beanName.equals("user")){
            System.out.println("干预原本的bean的生命周期,生成其他对象实例");
            return new Order();
        }
        return null;
    }

}

推断构造方法和实例化

回到createBean方法中 继续向下走,有这么一句代码。去做创建bean的操作

Object beanInstance = doCreateBean(beanName, mbdToUse, args);

进入doCreateBean方法查看。

        BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
             //在这里去执行了bean的实例化
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
        //原始对象
		final Object bean = instanceWrapper.getWrappedInstance();
		//原始对象的class类型
        Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

createBeanInstance方法中进行了构造方法的推断以及实例化,作为单独篇章分析:https://blog.csdn.net/qq_39404258/article/details/109769278

beanDefinition的后置处理

在doCreateBean方法中继续走,到这里进行beanDefinition的后置处理

// 允许后处理程序修改合并的bean定义。
synchronized (mbd.postProcessingLock) {
   if (!mbd.postProcessed) {
      try {
          //在这里可以添加修改beanDefinition的内容,可以算作一个beanPostProcessor的扩展点
         applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
      }
      catch (Throwable ex) {
         throw new BeanCreationException(mbd.getResourceDescription(), beanName,
               "Post-processing of merged bean definition failed", ex);
      }
      mbd.postProcessed = true;
   }
}

这里执行了applyMergedBeanDefinitionPostProcessors方法,原理都是beanPostProcessor。自定义beanPostProcessor通过实现MergedBeanDefinitionPostProcessor接口内的相应方法即可。

在doCreateBean方法中继续走,在这里进行了循环依赖的逻辑,作为单独篇章分析:https://blog.csdn.net/qq_39404258/article/details/108367587

// 如果当前创建的是单例bean,并且允许循环依赖,并且还在创建过程中,那么则提早暴露
      boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
      if (earlySingletonExposure) {
         if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                  "' to allow for resolving potential circular references");
         }
         // 此时的bean还没有完成属性注入,是一个非常简单的对象
         // 构造一个对象工厂添加到singletonFactories中,getEarlyBeanReference暂时没断点到,疑似lambda的问题
         addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));  
      }

// 该bean就是实例化对象
Object exposedObject = bean;

至此,已经获取到了实例化对象,接下来讲实例化对象进行属性填充。

实例化后

这时我们还在doCreateBean方法,下面这个方法是属性填充方法

populateBean(beanName, mbd, instanceWrapper);

进入这个方法,略过判空,看这段循环。只有postProcessAfterInstantiation返回值是false才会进行属性填充,否则直接结束属性填充。

// 在设置属性之前,给任何instantiationwarebeanpostprocessors机会修改bean的状态。
// 我们可以自己写一个InstantiationAwareBeanPostProcessor,然后重写postProcessAfterInstantiation(实例化后)方法来判断是否进行属性填充,
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         // 如果该方法返回false,那么则不会进行属性填充了,直接return了
         if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
            return;
         }
      }
   }
}

属性填充

接着向下走是进行属性填充(依赖注入),作为一个单独的篇章进行分析。

@autowired源码注入分析https://blog.csdn.net/qq_39404258/article/details/109472260

aware回调

结束属性填充,回到doCreateBean方法继续走。

//暴露这个对象
exposedObject = initializeBean(beanName, exposedObject, mbd);

然后进入initializeBean方法查看。

//安全处理器,没有忽略
if (System.getSecurityManager() != null) {
   AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      invokeAwareMethods(beanName, bean);
      return null;
   }, getAccessControlContext());
}
else {
    //调用aware回调
   invokeAwareMethods(beanName, bean);
}

初始化

在这个initializeBean方法内继续向下走,执行初始化前、初始化、初始化后方法。

Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
//执行postProcessBeforeInitialization() 方法(初始化前)
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
         //执行初始化方法init,需实现InitializingBean接口
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
//执行postProcessAfterInitialization() 方法(初始化后)
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

销毁注册

再回到doCreateBean方法,最后面有一个这样的方法registerDisposableBeanIfNecessary,用于将实现了DisposableBean接口的bean注册进去用于close时的销毁。

registerDisposableBeanIfNecessary(beanName, bean, mbd);

以上为bean的部分生命周期::(加载类)-> 实例化->(填充属性)->(aware回调)->初始化。

总结一下在bean的生命周期里需要使用到的接口以及扩展的beanPostProcessor

1.加载类

2.实例化前  InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation

3.实例化 暂时没有分析

插入了一个beanDefinition后置处理器  MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition

4.实例化后 InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation

5.填充属性 InstantiationAwareBeanPostProcessor.postProcessProperties

6.aware回调

7.初始化前 BeanPostProcessor.postProcessBeforeInitialization

8.初始化 InitializingBean.afterPropertiesSet,当然不止这一种可以初始化,注解(@PostConstruct)和xml(init-method)方式都可以

9.初始化后 BeanPostProcessor.postProcessAfterInitialization

10.bean使用中

11.bean销毁 DisposableBean.destroy,当然不止这一种可以销毁,注解(@PreDestroy)和xml(destroy-method)方式都可以

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值