- Spring启动,查找并加载需要被Spring管理的Bean,进行Bean的实例化(反射机制);
- 利用依赖注入完成 Bean 中所有属性值的配置注入;
第一类Aware接口:
- 如果 Bean 实现了 BeanNameAware 接口的话,Spring 将 Bean 的 Id 传递给 setBeanName() 方法;
- 如果 Bean 实现了 BeanClassLoaderAware 接口,则 Spring 调用 setBeanClassLoader() 方法传入classLoader的引用;
- 如果 Bean 实现了 BeanFactoryAware 接口的话,则 Spring 调用 setBeanFactory() 方法传入当前工厂实例的引用;
第二类Aware接口:
- 如果 Bean 实现了 EnvironmentAware 接口,则 Spring 调用 setEnvironment() 方法传入当前 Environment 实例的引用;
- 如果 Bean 实现了 EmbeddedValueResolverAware 接口,则 Spring 调用 setEmbeddedValueResolver() 方法传入当前 StringValueResolver 实例的引用;
- 如果 Bean 实现了 ApplicationContextAware 接口,Spring 将调用 Bean 的 setApplicationContext() 方法,将 Bean 所在引用上下文引用传入进来;
- 如果 Bean 实现了 BeanPostProcessor 接口,Spring 就将调用它们的 postProcessBeforeInitialization() 方法;
- 如果 Bean 实现了 InitializingBean 接口,Spring 将调用它们的 afterPropertiesSet() 方法。类似地,如果 Bean 使用 init-method 声明了初始化方法,该方法也会被调用;
- 如果 Bean 实现了 BeanPostProcessor 接口,**Spring 就将调用它们的 postProcessAfterInitialization() 方法;**此时,Bean 已经准备就绪,可以被应用程序使用了。它们将一直驻留在应用上下文中,直到应用上下文被销毁;
- 如果 Bean 实现了 DisposableBean 接口,Spring 将调用它的 destory() 接口方法,同样,如果 Bean 使用了 destory-method 声明销毁方法,该方法也会被调用;
- 如果在
<bean>
中指定了该 Bean 的作用范围为 scope=“singleton”,则将该 Bean 放入 Spring IoC 的缓存池中,将触发 Spring 对该 Bean 的生命周期管理;如果在<bean>
中指定了该 Bean 的作用范围为 scope=“prototype”,则将该 Bean 交给调用者,调用者管理该 Bean 的生命周期,Spring 不再管理该 Bean。
综上所述,Bean的完整生命周期有各种方法调用,主要分为这几类
- Bean自身的方法: 这个包括了Bean本身调用的方法和通过配置文件中
<bean>
的init-method和destroy-method指定的方法;- Bean级生命周期接口方法: 这个包括了BeanNameAware、BeanFactoryAware、ApplicationContextAware;当然也包括InitializingBean和DiposableBean这些接口的方法(可以被@PostConstruct和@PreDestroy注解替代);
- 容器级生命周期接口方法: 这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”;
- 工厂后处理器接口方法: 这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。
主要的生命周期总结
主要说明一下生产和销毁过程
- 生产
- 使用
- 销毁
1. 生产
这个部分最为复杂
当系统开始准备容器时,生成bean的过程就开始了,启动开始时,首先会调用加载Bean定义的
loadBeanDefinitions
方法,采用xml或者注解扫描等方式将程序员定义的Bean都找到,然后存储到容器中,容器中会定义一个beanDefinitionMap(bean定义集合),存储在其中;
有了Bean定义集合之后,就可以进行遍历了,然后通过createBean方法创建Bean对象了;
而在这里创建Bean对象的过程比较复杂,主要分为构造对象、填充属性、初始化实例以及注册销毁四个步骤
- 构造对象:调用createBeanInstance方法,通过反射机制从“Bean定义”中的BeanClass拿到这个类的构造方法;
但是调用构造方法时,如果是单个构造方法,那会直接调用,如果是多个构造方法,优先拿@Autowired注解的构造方法;如果多个注解的情况,报错~;如果都没有注解,优先拿无参构造方法;如果多个构造方法都是有参数,报错;
当选择了构造方法之后,需要准备该构造方法的参数,在单例池中,根据参数的Class类进行查找,如果该类在容器中有多个实例,则会根据参数名再进行匹配,如果没有找到,则会判断构造信息不完整而报错,参数准备好之后,就可以实例化了(反射机制)。当然如果是无参构造器,则无需参数即可构造;
- 填充属性:通过populateBean方法为Bean内部的所需的属性进行赋值填充,通常就是@Autowired注解的变量
通过“三级缓存”机制进行填充,也就是依赖注入
- 初始化实例:通过InitializingBean 接口,Spring 将调用它们的 afterPropertiesSet() 方法,初始化的第一步是初始化容器相关信息,通过
invokeAwareMeathods
方法为实现了各种Aware接口的Bean设置,例如:beanName、beanFactory等容器信息,这里的Aware代表信息感知接口,一旦实现了这些接口,就可以在bean实例中感知并获取到对应的信息;
接下来就是通过invokeInitMeathods
方法执行Bean的初始化方法了,这个方法就是通过实现InitializingBean接口的
afterPropertiesSet()
方法,该方法表示“Bean填充属性后”执行;
在执行afterPropertiesSet()
方法之后,还会继续执行我们在Bean上定义的initMethod方法,在执行初始化方法之前和之后,还需要对“Bean后置处理器”BeanPostProcessors进行处理,这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”;
- 注册销毁:通过注册registerDisposableBean方法,将实现销毁接口DisposableBean的Bean进行注册,这样在销毁时就可以执行destory()方法了
通过以上四步,bean就创建好了
最后只需要将这些完整的Bean对象通过addSingleton方法放入单例池singletonObjects中就可以被获取和使用了,这样产生bean就完成了,bean就可以使用了
2. 销毁
和产生Bean类似,在销毁之前执行销毁处理器POSTProcessBeforeDestruction;
这里就会执行Bean中@PreDestroy注解的方法,然后通过destroyBeans方法逐一销毁容器(singletonObjects)中的所有的Bean;
也会通过客户销毁方法invokeCustomDestroyMethod来执行Bean用户自定义的destroyMethod方法
综上所述,Bean的生命周期就完成了