庖丁解牛之spring源码系列二 spring bean生命周期介绍

        这篇本来要介绍这个finishBeanFactoryInitialization(beanFactory)实例化方法的,但考虑到这里面涉及的东西实在很多,决定进行拆分介绍,先介绍spring bean的生命周期、生命周期在源码的体现以及怎么完成自动注入的、然后在介绍spring怎么解决循环依赖的。这篇先来介绍下spring bean的生命周期。

生命周期概览

        spring生命周期从总体上说,分为实例化之前,实例化,实例化之后,自动注入,AWare,初始化之前,初始化,初始化之后这些流程,具体各流程代码方法调用顺序体现为以下:

实例化之前

1、InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation 方法、

实例化

2、构造方法

实例化之后

3、MergedBeanDefinitionPostProcessor#postProcessMergedBeanDefinition方法

4、InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation方法

5、InstantiationAwareBeanPostProcessor#postProcessProperties方法

自动注入

6、自动注入

AWare

7、各种Aware的调用,

初始化之前

8、PostConstruct注解(注意这个我放到初始化之前阶段)

9、BeanPostProcessor#postProcessBeforeInitialization方法

初始化

10、InitializingBean#afterPropertiesSet方法

初始化之后

11、BeanPostProcessor#postProcessAfterInitialization方法

销毁

12、销毁方法。

生命周期详解

        spring生命周期包括以下流程,实例化之前,实例化,实例化之后,自动注入,AWare,初始化之前,初始化,初始化之后,销毁,牢记这些流程,下面就是已这个流程顺序进行分析。spring提供相应的钩子,供用户自定义这些流程。InstantiationAwareBeanPostProcessor是实例化之前,实例化之后的钩子,一共有3个方法,postProcessBeforeInstantiation,postProcessAfterInstantiation,postProcessProperties。postProcessBeforeInstantiation方法作用于实例化之前,如果返回不为null,这个bean对象的生命周期会直接跳到初始化之后这一个流程,aop正是通过postProcessBeforeInstantiation方法返回一个代理对象,进而实现代理,postProcessAfterInstantiation方法是在实例化之后调用的,返回值为一个布尔值,如果返回为true,则会调用postProcessProperties方法,进行bean属性的后置处理。如果返回为false,则不会调用postProcessProperties,也不会进行属性注入。

public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {

	/**
	 *在实例化对象之前调用,这里可以返回一个代理对象,当返回不为null,会直接调用
     *BeanPostProcessor的postProcessAfterInitialization方法       
	 */
	@Nullable
	default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		return null;
	}

	/**
     *在实例化之后调用,属性注入之前调用。如果返回为false,则不进行属性注入过程,返回为true的调 
     *用下面postProcessProperties方法。
	 */
	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
		return true;
	}

	/**
     *后置处理bean的属性值,
	 */
	@Nullable
	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
			throws BeansException {

		return null;
	}

	/**
     *已废弃
	 */
	@Deprecated
	@Nullable
	default PropertyValues postProcessPropertyValues(
			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

		return pvs;
	}

}

         在实例化之后这一流程,还有一个钩子,就是MergedBeanDefinitionPostProcessor,它的调用时机为InstantiationAwareBeanPostProcessor #postProcessAfterInstantiation方法之前,实例化之后。要理解MergedBeanDefinitionPostProcessor,先得理解MergedBeanDefinition,当然spring没这个官方概念的,它翻译为已合并的BeanDefinition。这里可能感到奇怪,啥叫已合并,其实在spring创建bean的过程中,可能不只需要一个beanDefinition,而需要多个beanDefinition。比如在student类继承person类型,在创建student类的bean时,需要student和person的beanDefinition,也就是说,spring是以MergedBeanDefinition为原料,创建bean的。MergedBeanDefinitionPostProcessor就是用对MergedBeanDefinition初始化或者一些元数据,这些元数据可以供InstantiationAwareBeanPostProcessor #postProcessProperties方法使用,进行属性赋值,spring 自动注入也是利用这原理进行实现的,具体实现为AutowiredAnnotationBeanPostProcessor,它实现了InstantiationAwareBeanPostProcessor和MergedBeanDefinitionPostProcessor,AutowiredAnnotationBeanPostProcessor先通过MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法,获取到InjectionMetadata对象,这个对象保存了bean需要注入的元数据,有了这个InjectionMetadata对象,再通过InstantiationAwareBeanPostProcessor #postProcessProperties方法完成属性的自动注入。

        通过上面,我们已经明白了实例化之前,实例化,实例化之后,自动注入这四个流程中,spring提供的生命周期钩子,主要是两个接口,InstantiationAwareBeanPostProcessor,MergedBeanDefinitionPostProcessor。而自动注入也是通过实现这两个钩子,进而完成注入流程。

        Aware的中文意思为感知,当某个bean实现了xxxAware接口时,就表示bean就能获得xxx,spring 提供Aware有BeanNameAware 、BeanClassLoaderAware 、 BeanFactoryAware 、ResourceLoaderAware 、 ApplicationContextAware 、MessageSourceAware 、ApplicationEventPublisherAware等等,下面这个Student类实现了ApplicationContextAware接口,就代表Student类能感知到ApplicationContext,在以后的方法就可以使用ApplicationContext这个对象。

@Component
public class Student implements ApplicationContextAware {
    private ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext=applicationContext;
    }
    public void test(){
        //因为实现了ApplicationContextAware 接口,所以就能在test方法中使用applicationContext对象。
        System.out.println(applicationContext);
    }
}

        初始化主要的方式为实现InitializingBean接口。至于初始化之前和初始化之后的生命周期钩子,就是BeanPostProcessor接口了,它有个两个方法,postProcessBeforeInitialization,postProcessAfterInitialization,为初始化前,初始化后的回调方法。销毁方法就是DisposableBean的提供方法了。

        好了,上面就是我对spring bean生命周期的理解,下篇详解生命周期在源码体现,以及怎么实现自动注入的。

 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值