Spring Bean的生命周期

在这里插入图片描述
如上图所示为Spring中Bean的一个完整生命周期,大体上可以分为实例化Instantiation、填充内部属性(属性赋值)Populate、初始化Initialization、销毁Destruction四个阶段。

实例化前准备阶段

从我的理解来说,它并不包含在bean的生命周期中,因为此时bean实例尚未创建,beanFactory中存储的仅是beanDefinition。通过实现BeanFactoryPostProcess接口的postProcessBeanFactory方法可以对beanDefinition进行修改,例如我们可以修改beanDefinition之间的依赖关系,例如aBeanDefinition.setDependsOn(bBeanDefinition),这样就表示在aBean创建前会先创建bBean,销毁bBean前会先销毁aBean。
但它是一个很重要的扩展点,可以通过实现接口来操作beanDefinition。

实例化、填充内部属性

  • 即图中的第2、3步,在Spring源码中对应AbstractAutowireCapableBeanFactory.java的doCreateBean方法中的
    createBeanInstance、populateBean方法。

在调用doCreateBean之前
会先进行一个resolveBeforeInstantiation操作,在这一步会给后置处理器一个机会返回代理对象,如果获取到了代理对象则直接返回不再进行后续创建过程,但是需要类是TargetSource类型,它是一个Aop框架接口一般不会用到它所以基本返回都是null。在这一步中会获取所有实现了InstantiationAwareBeanPostProcessor接口的类,调用它们的postProcessBeforeInstantiation(Class<?> beanClass, String beanName)方法。我们经常说的AOP,利用的是代理模式,很核心的一点就是生成一个代理对象,相关类为AbstractAutoProxyCreator,它实现了SmartInstantiationAwareBeanPostProcessor接口,它也是在这一步根据类有没有实现接口采用JDK或CGLIB的形式来获取代理对象。

且SmartInstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口并包含getEarlyBeanReference方法,其实大部分代理对象的创建是通过AbstractAutoProxyCreator的postProcessAfterInitialization()或getEarlyBeanReference方法创建的。
之后在populateBean方法中会先调用InstantiationAwarePostProcessor的postProcessAfterInstantiation
在调用InstantiationAwarePostProcessor的postProcessPropertyValues(对将要填充的属性进行处理)
之后再进行属性填充

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
			throws BeanCreationException {
         // Instantiate the bean.   执行构造方法实例化bean -> 2
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		....
		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
		    //填充内部属性 -> 3
			populateBean(beanName, mbd, instanceWrapper);
			if (exposedObject != null) {
			    // 初始化 -> 4-8
				exposedObject = initializeBean(beanName, exposedObject, mbd);
			}
		}
   .....
   // Register bean as disposable.  注册销毁回调函数
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
}

初始化阶段

在上面代码块中对应initializeBean中的部分,这一块包含了图中的第4到8步且为我们提供了众多扩展点,进入方法展开说一下

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				@Override
				public Object run() {
				    //检查有没有实现aware相关接口 -> 4
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
		    //执行BeanPostProcessor.postProcessBeforeInitialization方法  -> 5
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
		    // 判断bean有没有实现InitializingBean接口,如果有实现则执行afterPropertiesSet()方法 ->6
		    // 如果bean有定义自己的init-method方法则执行 ->7
			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()) {
		    //执行BeanPostProcessor.postProcessAfterInitialization(wrappedBean, beanname) -> 8
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
  • 图中第4步,在invokeAwareMethods方法中会检查bean有没有实现BeanNameAware、BeanFactoryAware、BeanClassLoaderAware接口,如果实现了,则会调用相关方法将对应Spring容器资源赋值方法。
private void invokeAwareMethods(final String beanName, final Object bean) {
		if (bean instanceof Aware) {
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			if (bean instanceof BeanClassLoaderAware) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
  • 在第5步,很简单就是找出所有实现了BeanPostProcessor接口的实现类,执行它们的postProcessBeforeInitialization(WrappedBean, beanName)方法。在上面第4步检查Aware接口设置相关属性,都是与SpringFactory相关的,其实ApplicationContext也会有自己的Aware,就是在这一步进行检查并设置的。相关的类名为ApplicationContextAwareProcessor,它会检查bean有没有实现EnvironmentAware、ApplicationContextAware等接口,将相关属性进行赋值操作

  • 在invokeInitMethods方法中包含了第6-7步,代码如下

protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		....
		// -> 6
		((InitializingBean) bean).afterPropertiesSet();
		...
		}

		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
					// ->7
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

首先是判断bean有没有实现InitializingBean接口如果实现了,则执行afterPropertiesSet()方法,需要注意的是该方法是针对单个bean的,而BeanPostProcess应用于所有的bean;该方法并没用参数,一般是进行一些属性的校验或修改。
之后会检查是否有initMethod方法,如果指定了则执行该方法。java中指定初始化方法有两种方式,一种是使用xml配置bean的方式<bean id=“myBean” class=“xxxx.MyBean” init-method=“init” destroy-method="destroy”>,另外一种是使用注解的方式@Bean(initMethod =“init” ,destroyMethod =“destroy” )。大家常说的@PostConstruct严格来说并不能算是一种initMethod,它的实现还是利用了BeanPostProcess,在CommonAnnotationBeanPostProcessor类中将所有被@PostContruct和@PreDestroy注解标注的方法识别出来,被@PostContruct方法标注的方法放在InitDestroyAnnotationBeanPostProcessor的postProcessBeforeInitialization中执行。

  • 在第8步则是执行所有BeanPostProcessor实现类的的postProcessAfterInitialization方法

  • 第9步需要注册bean销毁时的回调函数
    首先会判断该bean是否需要注册销毁回调函数,具体判断逻辑在registerDisposableBeanIfNecessary(beanName, bean, mbd)中的requiresDestruction(Object bean, RootBeanDefinition mbd)方法

protected boolean requiresDestruction(Object bean, RootBeanDefinition mbd) {
		return (bean != null &&
				(DisposableBeanAdapter.hasDestroyMethod(bean, mbd) || (hasDestructionAwareBeanPostProcessors() &&
						DisposableBeanAdapter.hasApplicableProcessors(bean, getBeanPostProcessors()))));
	}

//DisposableBeanAdapter
public static boolean hasDestroyMethod(Object bean, RootBeanDefinition beanDefinition) {
		if (bean instanceof DisposableBean || closeableInterface.isInstance(bean)) {
			return true;
		}
		String destroyMethodName = beanDefinition.getDestroyMethodName();
		if (AbstractBeanDefinition.INFER_METHOD.equals(destroyMethodName)) {
			return (ClassUtils.hasMethod(bean.getClass(), CLOSE_METHOD_NAME) ||
					ClassUtils.hasMethod(bean.getClass(), SHUTDOWN_METHOD_NAME));
		}
		return StringUtils.hasLength(destroyMethodName);
	}

public static boolean hasApplicableProcessors(Object bean, List<BeanPostProcessor> postProcessors) {
		if (!CollectionUtils.isEmpty(postProcessors)) {
			for (BeanPostProcessor processor : postProcessors) {
				if (processor instanceof DestructionAwareBeanPostProcessor) {
					DestructionAwareBeanPostProcessor dabpp = (DestructionAwareBeanPostProcessor) processor;
					try {
						if (dabpp.requiresDestruction(bean)) {
							return true;
						}
					}
					catch (AbstractMethodError err) {
						// A pre-4.3 third-party DestructionAwareBeanPostProcessor...
						// As of 5.0, we can let requiresDestruction be a Java 8 default method which returns true.
						return true;
					}
				}
			}
		}
		return false;
	}

如果bean包含有destroyMethod方法(包括在xml中、@Bean中指明destroyMethod),或者实现了DisposableBean接口,或者当前实现了DestructionAwareBeanPostProcessor
接口的实现类适用于该bean,则根据该bean的创建DisposableBeanAdapter对象,获取所有适用该bean的DestructionAwareBeanPostProcessor对象,并将disposableBeanAdapter对象存储进disposableBeans Map中。此时销毁时的回调函数注册完毕

bean销毁

经历过上述阶段之后,bean已经创建成功了,正常运行之后,在进行销毁时,会调用注册的回调函数。从disposableBeans map中获取对应的disposableBeanAdapter对象,DisposableBeanAdapter也实现了DisposableBean接口重写了的destroy方法。在其中首先会判断如果有DestructionAwareBeanPostProcessor适用于该bean,会调用其postProcessBeforeDestruction方法;其次如果该bean本身就实现了DisposableBean接口,也会调用destroy方法;最后执行该bean自定义的的distroyMethod方法,之后进行销毁。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值