对象如何诞生与毁灭:解析Spring中的对象生命周期

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 对象如何诞生与毁灭:解析Spring中的对象生命周期

什么是 Spring 对象的生命周期

所谓的生命周期指的是一个对象从诞生到销毁的整个生命过程,我们把这个过程就叫做一个对象的生命周期。Bean 的生命周期分为以下 5 大部分:

  1. 实例化:当 Spring 容器接收到一个 Bean 的定义时,会根据该定义创建一个 Bean 的实例。
  2. 属性赋值:创建 Bean 的实例后,Spring 通过反射机制将 Bean 属性设置为相应的值。通常情况下,这些 Bean 属性的值来自于配置文件或注解等方式。
  3. 初始化:在 Bean 实例化并设置好所有属性之后,Spring 容器将调用特定的方法对 Bean 进行初始化,例如执行自定义的初始化方法或 BeanPostProcessor 接口中的回调方法等。
  4. 使用:当 Bean 初始化完成后,它可以被 Spring 容器使用了。在此阶段,Bean 可以响应容器中的请求,执行相应的业务逻辑。
  5. 销毁:当应用程序关闭或者 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 的生命周期(完整版)

  1. Bean 容器找到配置文件中 Spring Bean 的定义。
  2. Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
  3. 如果涉及到一些属性值 利用 set() 方法设置一些属性值。
  4. 如果 Bean 实现了 BeanNameAware 接口,调用 setBeanName() 方法,传入 Bean 的名字。
  5. 如果 Bean 实现了 BeanClassLoaderAware 接口,调用 setBeanClassLoader() 方法,传入 ClassLoader 对象的实例。
  6. 如果 Bean 实现了 BeanFactoryAware 接口,调用 setBeanFactory()方法,传入 BeanFactory 对象的实例。
  7. 与上面的类似,如果实现了其他 *.Aware 接口,就调用相应的方法。
  8. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessBeforeInitialization() 方法。
  9. 如果 Bean 实现了 InitializingBean 接口,执行 afterPropertiesSet() 方法。
  10. 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
  11. 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行 postProcessAfterInitialization() 方法。
  12. 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
  13. 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。


相关文章
|
22天前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
65 2
|
22天前
|
前端开发 Java Spring
探索Spring MVC:@Controller注解的全面解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序的基石之一。它不仅简化了控制器的定义,还提供了一种优雅的方式来处理HTTP请求。本文将全面解析`@Controller`注解,包括其定义、用法、以及在Spring MVC中的作用。
40 2
|
23天前
|
前端开发 Java Maven
深入解析:如何用 Spring Boot 实现分页和排序
深入解析:如何用 Spring Boot 实现分页和排序
46 2
|
9天前
|
XML 安全 Java
Spring Boot中使用MapStruct进行对象映射
本文介绍如何在Spring Boot项目中使用MapStruct进行对象映射,探讨其性能高效、类型安全及易于集成等优势,并详细说明添加MapStruct依赖的步骤。
|
22天前
|
前端开发 Java 开发者
Spring MVC中的控制器:@Controller注解全解析
在Spring MVC框架中,`@Controller`注解是构建Web应用程序控制层的核心。它不仅简化了控制器的定义,还提供了灵活的请求映射和处理机制。本文将深入探讨`@Controller`注解的用法、特点以及在实际开发中的应用。
55 0
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
71 2
|
2月前
|
缓存 Java 程序员
Map - LinkedHashSet&Map源码解析
Map - LinkedHashSet&Map源码解析
76 0
|
2月前
|
算法 Java 容器
Map - HashSet & HashMap 源码解析
Map - HashSet & HashMap 源码解析
62 0
|
2月前
|
存储 Java C++
Collection-PriorityQueue源码解析
Collection-PriorityQueue源码解析
66 0
|
2月前
|
安全 Java 程序员
Collection-Stack&Queue源码解析
Collection-Stack&Queue源码解析
86 0

推荐镜像

更多
下一篇
DataWorks