天天看点

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。 是不能通过添加进无参构造器来实现的,会报空指针异常。