bean 的声明周期

bean 相关基础内容:5. bean 基础配置

一、关闭 Spring 容器的方法

在 JVM 退出时,不会给 Spring 执行 Destory 钩子的时间,所以需要手动进行关闭

暴力关闭

通过调用 ctx.close() 方法强行关闭容器,当关闭后,后续操作容器方法将会报错。

注意:ApplicationContext 类中,没有 close 方法,需要使用 ClassPathXmlApplicationContext 才可以使用 close 方法

1
2
3
4
5
6
7
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

ctx.close();
}
}

注册钩子

使用 ctx.registerShutdownHook 注册 JVM 退出的钩子,让JVM在退出之前回调此函数来关闭容器,使用该方法不会影响后续代码。

1
2
3
4
5
6
7
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

ctx.registerShutdownHook();
}
}

区别

相同点: 这两种都能用来关闭容器

不同点: close()是在调用的时候关闭,registerShutdxownHook()是在JVM退出前调用关闭。

二、配置声明周期方法

Service 层

在 service 层新增 initdestroy 两个方法,用于作为 Bean 生命周期钩子函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class BookServiceImpl implements BookService {
private BookDao bookDao;

public void save() {
System.out.println("book service save ...");
bookDao.save();
}

public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}

public void init(){
System.out.println("init ...");
}

public void destroy(){
System.out.println("destroy ...");
}
}

配置

在配置中,bean 通过 init-methoddestroy-method 指定 service 类中抛出的钩子函数

  • init-method -> init : bean 初始化生命周期钩子
  • destory-method -> destory : bean 销毁生命周期钩子
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="bookDao" class="cn.pangcy.dao.impl.BookDaoImpl" />
<bean id="bookService" class="cn.pangcy.service.impl.BookServiceImpl" init-method="init" destroy-method="destroy">
<property name="bookDao" ref="bookDao" />
</bean>
</beans>

三、通过接口实现生命周期钩子

通过实现 InitializingBeanDisposableBean 两个类,并重写 afterPropertiesSetdestroy 实现声明周期钩子函数

  • InitializingBean -> afterPropertiesSet : bean 初始化钩子
  • DisposableBean -> detroy : bean 销毁钩子
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {
private BookDao bookDao;

public void save() {
System.out.println("book service save ...");
bookDao.save();
}

public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}

@Override
public void afterPropertiesSet() throws Exception {
System.out.println("service init ...");
}

@Override
public void destroy(){
System.out.println("service destroy ...");
}

}

配置

配置中无需额外配置,也不需要 init-methoddestroy-method 属性。

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

<bean id="bookDao" class="cn.pangcy.dao.impl.BookDaoImpl" />
<bean id="bookService" class="cn.pangcy.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDao" />
</bean>
</beans>

输出结果

bean 生命周期

  • 初始化容器
    1. 创建对象( 内存分配 )
    2. 执行构造方法
    3. 执行属性注入( set 操作 )
    4. 执行 bean初始化方法
  • 使用 bean
    1. 执行业务操作
  • 关闭/销毁容器
    1. 执行 bean销毁方法

bean 的销毁时机

  • 容器关闭前才会触发 bean 的销毁
  • 关闭容器方式
    • 手动关闭容器
      • ConfigurableApplicationContext 接口中的 close() 操作
    • 注册关闭钩子,在虚拟机退出前先关闭容器再退出虚拟机
      • ConfigurableApplicationContext 接口中的 registerShutdownHook() 操作

bean 的声明周期
https://blog.pangcy.cn/2023/04/03/后端编程相关/java/spring/bean 的声明周期/
作者
子洋
发布于
2023年4月3日
许可协议