spring控制bean生命周期(spring控制的bean初始化与销毁的执行方法)
之前项目中,需要用到在项目启动时,就要在某个类中执行一些方法。在我的记忆中我只知道在bean的配置中加init-method这种方法。这两天在浏览spring官方文档中,发现还有其他的方法,于是拿出来总结一下,以方便后续开发中使用。
spring在控制bean生命周期的整个过程中,给开发者提供了初始化与销毁bean时需要做自己的处理的三种方式(我用的spring5.1.3版本)
1.在需要bean初始化、销毁时执行的方法前加@PostConstruct或@PreDestroy
例如:
@PostConstruct
public void populate() {
System.out.println("实现@PostConstruct的方法");
}
@PreDestroy
public void clear() {
System.out.println("实现@PreDestroy的方法");
}
2.使需要拥有初始化、销毁的方法的bean实现InitializingBean,DisposableBean两个接口
例如:
public class Demo implements InitializingBean,DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("实现InitializingBean接口的方法");
}
@Override
public void destroy() throws Exception {
System.out.println("实现DisposableBean接口的方法");
}
}
3.需要在spring配置文件相关bean的配置中添加init-method="方法名" destroy-method="方法名"属性
例如:
配置文件:
<bean id="demo" class="com.Demo" init-method="init" destroy-method="over" lazy-init="false"/>
代码:
public class Demo{
public void init(){
System.out.println("init");
}
public void over(){
System.out.println("over");
}
}
lazy-init="false"这个属性是为了,防止类在项目用到此类时才加载的控制,我这没有加lazy-init="false"其实也生效的。这个要看你的类配置在作用项目全局中,还是某个servlet作用域中。
我在一个类中分别实现了这三种方式,如下:
@Component
public class Demo implements InitializingBean,DisposableBean {
//@Resource(name = "algorithmProperty")
//private AlgorithmProperty algorithmProperty;
public Demo() {
System.out.println("构造器");
}
public void init(){
System.out.println("init");
}
public void over(){
System.out.println("over");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("实现InitializingBean接口的方法");
}
@Override
public void destroy() throws Exception {
System.out.println("实现DisposableBean接口的方法");
}
@PostConstruct
public void populate() {
System.out.println("实现@PostConstruct的方法");
}
@PreDestroy
public void clear() {
System.out.println("实现@PreDestroy的方法");
}
}
1.启动项目
控制台输出:
构造器
实现@PostConstruct的方法
实现InitializingBean接口的方法
init
2.停止项目
控制台输出:
实现@PreDestroy的方法
实现DisposableBean接口的方法
over
我本地实现的现象是这样可以,启动与停止执行三种方式的顺序。重复了多次依然是一样的,这个为什么只有后续研究源码考究了。
需要注意的是:我为什么要加构造器呢,并且得到了执行。说明spring容器的bean控制,是通过bean的无参构造器完成的。
再一点,我的例子中,有两行注释的代码:
//@Resource(name = "algorithmProperty")
//private AlgorithmProperty algorithmProperty;
通过验证,这个类的这个属性,一般情况下是在所有的需要spring加载的bean加载完,才进行依赖注入的。 并且注入完所有的属性之后,才执行上述的三种实现方法。 也就是说,如果在需要某个bean初始化时,执行你自定义的方法,你的方法中又需要其他的spring控制的bean。 是不能通过添加进无参构造器来实现的,会报空指针异常。
推荐阅读
-
spring初始化bean时执行某些方法完成特定的初始化操作
-
Spring中Bean的生命周期自定义销毁和初始化方法实现详解
-
spring注册组件——@Bean的生命周期(指定初始化和销毁方法)示例
-
spring源码分析系列5:ApplicationContext的初始化与Bean生命周期
-
【Spring】【Bean的scope属性】【Bean的初始化和销毁方法】
-
spring初始化bean和销毁bean时调用的方法
-
spring Bean的初始化和销毁生命周期方法
-
Spring指定Bean的初始化方法和销毁方法
-
Spring Bean的初始化和销毁方法一:通过设置bean的initMethod和destroyMethod属性指定初始化和销毁方法。
-
Spring中Bean初始化和销毁方法执行的优先级