Spring中Bean的生命周期及源码详解

Spring Bean 实例化步骤

  • 推断构造方法
  • 通过构造方法创建对象
  • 填充属性,即依赖注入
  • 处理ApplicationContextAware接口的回调,即处理ApplicationContextAware接口的setApplicationContext方法
  • 初始化前,即处理@PostConstruct注解的方法
  • 初始化,即处理InitializingBean接口的afterPropertiesSet方法
  • 初始化后,AOP。

代码验证

BeanInitTest实现了ApplicationContextAware、InitializingBean 接口,且用 @PostConstruct注解声明了初始化前方法,声明了一个切面AopAspectTest,使得BeanInitTest是AOP代理对象。

如果在afterPropertiesSet、setApplicationContext、beforeInit方法上打断点,调试启动,会发现依次顺序进入setApplicationContext、beforeInit、afterPropertiesSet方法。

@Service
public class BeanInitTest implements ApplicationContextAware, InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("初始化");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("ApplicationContextAware 回调方法");
    }
    @PostConstruct
    private void beforeInit(){
        System.out.println("初始化前");
    }
}
@Component
@Aspect
public class AopAspectTest {
    @Pointcut(" execution (* com.ludk.weixin.service.BeanInitTest.*(..))")
    public void pointCut(){}

    @Before("pointCut()")
    public void cutBefore(){
        System.out.println("切面方法前");
    }

}

代码调试验证

断点选择

在如图所示处打断点,并加上条件beanName.equals(“beanInitTest”),只观察该bean对象实例化,然后调试启动SpringBoot项目在这里插入图片描述

调试观察

进入断点后,如下图所示,左下角是代码调用的堆栈信息,可以看到代码的来源,beanName确实是想监控的bean名称beanInitTest
在这里插入图片描述

创建bean的代码分析并验证

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

		// Instantiate the bean.
		//创建Bean的时候,会将Bean包装成一个BeanWrapper
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			//创建Bean实例,里面包含推断构造方法,并根据构造方法利用反射实例化Bean对象
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		Object bean = instanceWrapper.getWrappedInstance();
		Class<?> beanType = instanceWrapper.getWrappedClass();
		if (beanType != NullBean.class) {
			mbd.resolvedTargetType = beanType;
		}

		// Allow post-processors to modify the merged bean definition.
		synchronized (mbd.postProcessingLock) {
			if (!mbd.postProcessed) {
				try {
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}
		}

		// 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));
		if (earlySingletonExposure) {
			if (logger.isTraceEnabled()) {
				logger.trace("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			//将对象工厂放入到Spring的三级缓存中
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			//填充属性,也就是依赖注入
			populateBean(beanName, mbd, instanceWrapper);
			//这里会处理ApplicationContextAware接口的回调、执行初始化前(@PostConstruct注解标注的方法)、初始化(InitializingBean接口方法)、初始化后的操作(AOP代理对象生成)
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}
		catch (Throwable ex) {
			if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
				throw (BeanCreationException) ex;
			}
			else {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
			}
		}

		if (earlySingletonExposure) {
			Object earlySingletonReference = getSingleton(beanName, false);
			if (earlySingletonReference != null) {
				if (exposedObject == bean) {
					exposedObject = earlySingletonReference;
				}
				else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
					String[] dependentBeans = getDependentBeans(beanName);
					Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
					for (String dependentBean : dependentBeans) {
						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 " +
								"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
					}
				}
			}
		}

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		return exposedObject;
	}

对象创建

doCreateBean的方法中对象创建的代码如下:

if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)方法参数

  • String beanName:bean名称
  • RootBeanDefinition mbd:bean的定义
  • @Nullable Object[] args:构造方法的参数

根据上面的三个参数推断出构造方法,利用java反射创建对象,相当于new了一个对象。

依赖注入

doCreateBean方法中依赖注入的代码如下:

populateBean(beanName, mbd, instanceWrapper);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw)方法参数

  • String beanName:bean名称
  • RootBeanDefinition mbd:bean的定义
  • @Nullable BeanWrapper bw:bean实例的包装类

依赖注入就是属性填充。上一步只是实例化了对象,对象中属性是null需要调用populateBean方法填充属性。

处理回调、初始化前、初始化、初始化后

doCreateBean方法中Bean初始化前、初始化、初始化后的代码如下:

exposedObject = initializeBean(beanName, exposedObject, mbd);

三个方法均打上断点,监控方法的调用链
在这里插入图片描述
方法依次进入ApplicationContextAware接口的setApplicationContext方法、InitializingBean接口的afterPropertiesSet方法、@PostConstruct注解注释的beforeInit方法,进入断点后同时观察左下角的方法调用链,分析代码。
在这里插入图片描述
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)是初始化bean的方法,里面主要包含初始化前、初始化、初始化后三个步骤。

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			//处理Aware接口的回调,其中包括ApplicationContextAware接口的setApplicationContext方法的执行
			//初始化前
			//都是用BeanProcess的前置处理方法实现的
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			//初始化 ,InitializingBean接口的afterPropertiesSet方法
			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()) {
			//初始化后,包括AOP
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

处理Aware回调

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

getBeanPostProcessors()获取Bean处理器时,有个
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

@Override
	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			//通过Bean的处理器,调用前置方法实现
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

BeanPostProcessor 是Bean的处理器,是、在容器初始化时对 bean 的创建过程进行扩展和自定义的接口。getBeanPostProcessors()方法获取各种Bean处理器,遍历调用前置方法,执行Bean初始化前的操作。

调试代码中是通过ApplicationContextAwareProcessor处理器,调用postProcessBeforeInitialization前置方法,就会执行到Bean对象ApplicationContextAware接口的setApplicationContext方法。

初始化前

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);

getBeanPostProcessors()获取Bean处理器时,有个CommonAnnotationBeanPostProcessor处理器,该处理器继承了InitDestroyAnnotationBeanPostProcessor处理器。

CommonAnnotationBeanPostProcessor的postProcessBeforeInstantiation实现是空的,因此执行父类InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization方法,最终执行到@PostConstruct注解标注的方法。调用链路如下:
在这里插入图片描述

初始化

invokeInitMethods(beanName, wrappedBean, mbd);

通过下面的代码调用
在这里插入图片描述
调用链路如下:
在这里插入图片描述

初始化后

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

getBeanPostProcessors()获取Bean处理器时,有个AnnotationAwareAspectJAutoProxyCreator处理器,它及它的父类均没有实现postProcessAfterInitialization方法,最后只能执行org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				//这里生成了AOP的代理对象
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

调用链路如下:
在这里插入图片描述

需要注意的是,如果是循环依赖的情况,是根据三级缓存中的对象工厂,创建AOP代理对象的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值