什么是 Spring 对象的生命周期
所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。Bean 的生命周期分为以下 5 大部分:
- 实例化:当 Spring 容器接收到一个 Bean 的定义时,会根据该定义创建一个 Bean 的实例。
- 属性赋值:创建 Bean 的实例后,Spring 通过反射机制将 Bean 属性设置为相应的值。通常情况下,这些 Bean 属性的值来自于配置文件或注解等方式。
- 初始化:在 Bean 实例化并设置好所有属性之后,Spring 容器将调用特定的方法对 Bean 进行初始化,例如执行自定义的初始化方法或 BeanPostProcessor 接口中的回调方法等。
- 使用:当 Bean 初始化完成后,它可以被 Spring 容器使用了。在此阶段,Bean 可以响应容器中的请求,执行相应的业务逻辑。
- 销毁:当应用程序关闭或者 Spring 容器销毁时,会调用已注册的 Bean 的销毁方法,以释放资源。这个销毁方法也可以是自定义的,需要实现 DisposableBean 接口或者添加 @PreDestroy 注解。
Spring 什么时候创建对象
scope=“singleton”
Spring 中的对象 默认是 singleton 的。而这类对象会在 Spring ⼯⼚创建的同时,完成对象的创建。即执行下面代码后:
context = new ClassPathXmlApplicationContext("/applicationContext.xml");
如果想要实现在获取的时候创建单例对象,那么可以在 Spring 的配置文件中指定属性:
<bean id="product" class="world.xuewei.life.Product" scope="singleton" lazy-init="true"/>
scope=“prototype”
如果对象被指定为多例的,那么对象的创建会发生在每次获取对象的时候,即执行下面代码后:
context = new ClassPathXmlApplicationContext("/applicationContext.xml"); Product product = context.getBean("product", Product.class);
对象初始化阶段
Spring ⼯⼚在创建完对象后,会调⽤对象的初始化⽅法,完成对应的初始化操作。初始化方法由程序员定义,由 Spring 框架调用。
InitializingBean 接口
进行初始化的第一种方式是对象需要实现 InitializingBean
接口,并实现 afterPropertiesSet
方法。
package world.xuewei.life; import org.springframework.beans.factory.InitializingBean; /** * 产品实体 * * @author 薛伟 * @since 2023/9/14 17:17 */ public class Product implements InitializingBean { public Product() { System.out.println("Product.Product"); } /** * 实现初始化方法 */ @Override public void afterPropertiesSet() throws Exception { System.out.println("Product.afterPropertiesSet"); } }
自定义初始化方法
在对象中定义一个普通的方法,可以避免 Spring 框架的侵入。
package world.xuewei.life; import org.springframework.beans.factory.InitializingBean; /** * 产品实体 * * @author 薛伟 * @since 2023/9/14 17:17 */ public class Product { public Product() { System.out.println("Product.Product"); } public void init() { System.out.println("Product.init"); } }
<bean id="product" class="world.xuewei.life.Product" init-method="init"/>
注意:上面的两种初始化方法可以同时存在,执行顺序 先 InitializingBean,后自定义方法。
注意:对象的属性注入是发生在初始化之前的!
什么是初始化操作
资源的初始化:数据库、IO、⽹络…
对象销毁阶段
Spring 销毁对象前,会调⽤对象的销毁⽅法,完成销毁操作。Spring 会在容器关闭的时候,即 context.close()
。完成对象的销毁,对象销毁方法由程序员定义,由 Spring 框架调用。
DisposableBean 接口
package world.xuewei.life; import org.springframework.beans.factory.DisposableBean; /** * 产品实体 * * @author 薛伟 * @since 2023/9/14 17:17 */ public class Product implements DisposableBean { public Product() { System.out.println("Product.Product"); } /** * 实现销毁方法 */ @Override public void destroy() throws Exception { System.out.println("Product.destroy"); } }
自定义销毁方法
在对象中定义一个普通的方法,可以避免 Spring 框架的侵入。
package world.xuewei.life; /** * 产品实体 * * @author 薛伟 * @since 2023/9/14 17:17 */ public class Product { public Product() { System.out.println("Product.Product"); } public void myDestroy() { System.out.println("Product.myDestroy"); } }
<bean id="product" class="world.xuewei.life.Product" destroy-method="myDestroy"/>
注意:上面的两种销毁方法可以同时存在,执行顺序 先 DisposableBean,后自定义方法。
注意:销毁的操作只适用于单例模式!scope=“singleton”
什么是销毁操作
资源的释放:流关闭、连接关闭…
Bean 的生命周期(完整版)
- Bean 容器找到配置文件中 Spring Bean 的定义。
- Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
- 如果涉及到一些属性值 利用
set()
方法设置一些属性值。 - 如果 Bean 实现了
BeanNameAware
接口,调用setBeanName()
方法,传入 Bean 的名字。 - 如果 Bean 实现了
BeanClassLoaderAware
接口,调用setBeanClassLoader()
方法,传入ClassLoader
对象的实例。 - 如果 Bean 实现了
BeanFactoryAware
接口,调用setBeanFactory()
方法,传入BeanFactory
对象的实例。 - 与上面的类似,如果实现了其他
*.Aware
接口,就调用相应的方法。 - 如果有和加载这个 Bean 的 Spring 容器相关的
BeanPostProcessor
对象,执行postProcessBeforeInitialization()
方法。 - 如果 Bean 实现了
InitializingBean
接口,执行afterPropertiesSet()
方法。 - 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
- 如果有和加载这个 Bean 的 Spring 容器相关的
BeanPostProcessor
对象,执行postProcessAfterInitialization()
方法。 - 当要销毁 Bean 的时候,如果 Bean 实现了
DisposableBean
接口,执行destroy()
方法。 - 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。