一、Spring中Bean的作用域
1、singleton作用域
如果bean的作用域的属性被声明为singleton,那么Spring IOC容器只会创建一个共享的bean实例。对于所有的bean请求,只要id与该bean定义的相匹配,那Spring每次需要时都会返回同一个bean实例。
2、prototype作用域
prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。
3、Request作用域
当http请求调用作用域为request的bean的时候,每增加一个HTTP请求,Spring就会创建一个新的bean,在请求处理完成之后便及时销毁这个bean。开发者可以随意改变实例的状态,因为通过Http请求来创建的其他实例根本看不到开发者改变的实例状态,所有创建的Bean实例都是根据独立的请求来的。
4、Session作用域
同一个HTTP Session共享一个Bean,不同Session使用不同的Bean。该作用域仅适用于web的Spring WebApplicationContext环境。
5、application作用域
限定一个Bean的作用域为ServletContext的生命周期。该作用域仅适用于web的Spring WebApplicationContext环境。
二、Spring Bean的生命周期
首先对于传统的java编程来说,一个对象的生命周期只有两步,第一步是实例化,第二步时该对象不再被使用时,通过垃圾回收机制进行回收。
对于Spring Bean的生命周期来说,主要分为接下来四步,分别是实例化,属性赋值,初始化,销毁四步。在Spring Bean的实例化和属性赋值以及初始化前后都会有各种拓展点,我们按照Spring Bean的生命周期依次介绍常用的拓展点。
1、对于Spring Bean在实例化之前和实例化之后的调用点
在SpringBean实例化之前有InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation调用点。在该调用点如果返回了bean实例,则会替代原来正常通过目标bean对象生成的bean的流程。典型的应用场景有aop返回proxy对象,此时的bean的执行流程将会缩短(实例化和初始化都不会执行),只会执行BeanPostProcessor接口中的postProcessAfterInitialization接口完成初始化。
在Spring Bean实例化之后,初始化之前,会调用InstantiationAwareBeanPostProcessor接口的postProcessAfterInstantiation调用点在实例化之后调用。如果此时有指定的bean的时候返回false,那么后续的属性填充和属性依赖注入(populateBean)将不会执行,但是后续的初始化和初始化前后的BeanPostProcessor仍然会执行。
2、对于Spring Bean在属性赋值前后的调用点
在上面的postProcessAfterInstantiation调用点返回为true时,InstantiationAwareBeanPostProcessor接口的postProcessProperties会调用,返回的PropertyValues(后面被改为postProcessProperties代替)将作用于给定bean属性赋值。如果返回的值为null,将不会进行后续的属性填充,如果返回的PropertyValues额外添加了属性,后续将会填充到该类对应的属性中。具体的方法如下所示:
public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)
3、对于Spring Bean在初始化方法前后的调用点
在对Spring Bean的属性进行填充之后,在Bean初始化之前会执行BeanPostProcessor接口的postProcessBeforeInitialization然后再执行执行InitializingBean的afterPropertiesSet。然后是属性配置的初始化方法。
最后在Bean初始化之后执行BeanPostProcessor接口的postProcessAfterInitialization。
4、Bean对象生成后销毁前的调用点
在Bean对象生成之后,如果该对象的作用域是prototype将该Bean给用户,剩下的生命周期由用户控制,如果Bean对象的作用域是singleton,返回Bean给用户并存入缓存池。
在Bean销毁前可以执行DisposableBean的destory,然后再执行Bean对象的销毁方法。
以上处理方法的图示如下所示:
该博客参考于:一文读懂 Spring Bean 的生命周期_spring bean的生命周期_老周聊架构的博客-CSDN博客