Spring之bean的生命周期
Spring之bean的生命周期
在传统的Java应用中,bean的生命周期很简单,使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了。一旦bean不再被使用,则由Java自动进行垃圾回收。
相比之下,Spring管理Bean的生命周期就复杂多了,正确理解Bean 的生命周期非常重要,因为Spring对Bean的管理可扩展性非常强,下面展示了一个Bean的构造过程
- Bean 容器找到配置文件中 Spring Bean 的定义。
- Bean 容器利用 Java Reflection API 创建一个 Bean 的实例。
- 如果涉及到一些属性值 利用 set()方法设置一些属性值。
- 如果实现了其他 *.Aware接口,就调用相应的方法。
- 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessBeforeInitialization() 方法
- 如果 Bean 实现了InitializingBean接口,执行afterPropertiesSet()方法。
- 如果 Bean 在配置文件中的定义包含 init-method 属性,执行指定的方法。
- 如果有和加载这个 Bean 的 Spring 容器相关的 BeanPostProcessor 对象,执行postProcessAfterInitialization() 方法
- 当要销毁 Bean 的时候,如果 Bean 实现了 DisposableBean 接口,执行 destroy() 方法。
- 当要销毁 Bean 的时候,如果 Bean 在配置文件中的定义包含 destroy-method 属性,执行指定的方法。
在 BeanFactory
的注释里,有这么一段话,如下图所示:
代码演示
- 新建一个
User
类,让其实现接口BeanNameAware
、BeanFactoryAware
、InitializingBean
和DiposableBean
这4个接口,以及编写userInit()
和userDestroy()
两个方法,对应配置文件中<bean>
的init-method
和destroy-method
。
package com.wqing.domain;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
/**
* @Description 用于演示 Bean 的生命周期
* @Author wqing
* @Date 2022/8/11 15:37
*/
public class User implements BeanNameAware, BeanFactoryAware,
InitializingBean, DisposableBean {
private String name;
private Integer age;
private BeanFactory beanFactory;
private String beanName;
public User() {
System.out.println("[构造器]--调用User的构造函数进行实例化");
}
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("[属性填充]--注入属性name");
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
System.out.println("[属性填充]--注入属性age");
this.age = age;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//这是 BeanFactoryAware 接口的方法
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:" + beanFactory);
this.beanFactory = beanFactory;
}
//这是 BeanNameAware 接口的方法
@Override
public void setBeanName(String name) {
System.out.println("[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: " + name);
this.beanName = name;
}
//这是 DisposableBean 接口的方法
@Override
public void destroy() throws Exception {
System.out.println("[DisposableBean]--执行DisposableBean.destroy()");
}
//这是 InitializingBean 接口的方法
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("[InitializingBean]--执行InitializingBean.afterPropertiesSet()");
}
// 通过<bean>的init-method属性指定的初始化方法
public void userInit() {
System.out.println("[init-method]--执行<bean>的init-method属性指定的初始化方法");
}
// 通过<bean>的destroy-method属性指定的初始化方法
public void userDestroy() {
System.out.println("[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法");
}
}
- 自定义
MyBeanPostProcessor
实现BeanPostProcessor
package com.wqing.domain;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
/**
* @Description
* @Author wqing
* @Date 2022/8/11 16:06
*/
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化任务
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()");
return bean;
}
/**
* 实例化、依赖注入、初始化完毕时执行
*/
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()");
return bean;
}
}
BeanPostProcessor
接口包括2个方法postProcessAfterInitialization
和postProcessBeforeInitialization
,这两个方法的第一个参数都是要处理的Bean对象,第二个参数都是Bean的name。返回值也都是要处理的Bean对象。
- 编写
application.xml
,将User
和MyBeanPostProcessor
注册进容器
<?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="user" class="com.wqing.domain.User" init-method="userInit"
destroy-method="userDestroy">
<property name="name" value="张三"/>
<property name="age" value="20"/>
</bean>
<bean id="myBeanPostProcessor" class="com.wqing.domain.MyBeanPostProcessor"/>
</beans>
- 编写测试类
package com.wqing;
import com.wqing.domain.User;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Description
* @Author wqing
* @Date 2022/8/5 14:38
*/
public class Test {
public static void main(String[] args) {
System.out.println("容器开始创建");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
User bean = context.getBean(User.class);
System.out.println("使用 bean");
System.out.println(bean);
System.out.println("容器开始销毁");
context.close();
}
}
执行结果
容器开始创建
[构造器]--调用User的构造函数进行实例化
[属性填充]--注入属性name
[属性填充]--注入属性age
[BeanNameAware]--执行BeanNameAware.setBeanName(),beanName为: user
[BeanFactoryAware]--执行BeanFactoryAware.setBeanFactory(),beanFactory为:org.springframework.beans.factory.support.DefaultListableBeanFactory@38082d64: defining beans [user,myBeanPostProcessor]; root of factory hierarchy
[BeanPostProcessor]--执行BeanPostProcessor.postProcessBeforeInitialization()
[InitializingBean]--执行InitializingBean.afterPropertiesSet()
[init-method]--执行<bean>的init-method属性指定的初始化方法
[BeanPostProcessor]--执行BeanPostProcessor.postProcessAfterInitialization()
使用 bean
User{name='张三', age=20}
容器开始销毁
[DisposableBean]--执行DisposableBean.destroy()
[destroy-method]--执行<bean>的destroy-method属性指定的销毁方法
本文作者:wqing's Blog
本文链接:https://www.cnblogs.com/wqstart/p/16576851.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。