Spring控制Bean生命周期行为的几种方式

前言:

    Spring中的Bean从创建到销毁经历了一个又一个阶段,在这些阶段中,我们可以通过某些方法来控制Bean的创建、Bean的销毁。

    在Spring的官方文档中,有这么一段话

As of Spring 2.5, you have three options for controlling bean lifecycle behavior: the InitializingBean and DisposableBean callback interfaces; custom init() and destroy() methods; and the @PostConstruct and @PreDestroy annotations. You can combine these mechanisms to control a given bean

   具体意思就是说:在Spring2.5以后,我们有三种方式来控制Bean的生命周期管理。

    1.通过InitializingBean和DisposableBean接口

    2.Bean的init()和destroy()方法

    3.@PostConstruct和@PreDestroy注解

    那我们就来看下这三种方式的实现

1.InitializingBean和DisposableBean接口

    1)我们首先来创建一个类,命名为LifeCycleBean,实现这两个接口,并实现其方法

public class LifeCycleBean implements Serializable , InitializingBean, DisposableBean {

    private static final long serialVersionUID = 2731651017595722776L;


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

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

    2)在beans.xml中定义该Bean

<bean id="lifeCycleBean" class="domain.LifeCycleBean"></bean>

    3)测试类测试生命周期方法

@Test
public void testXml(){
    ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    LifeCycleBean lifeCycleBean = (LifeCycleBean) applicationContext.getBean("lifeCycleBean");
    applicationContext.close();
}
// res
InitializingBean init...
DisposableBean destroy...

    总结:在LifeCycleBean被获取的时候,afterPropertiesSet()方法被调用;在容器关闭之前,destroy()方法被调用

2.Bean的init()和destroy()方法

    这种方式大家应该都比较了解了,在之前的文章中我们已经使用过这两个方法,这里再简单演示一下。

    1)在LifeCycleBean.java中添加方法xmlInit() xmlDestroy()

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

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

   2)beans.xml中定义的LifeCycleBean添加init-method和destroy-method指向xmlInit()和xmlDestroy()

<bean id="lifeCycleBean" class="domain.LifeCycleBean" init-method="xmlInit" destroy-method="xmlDestroy"></bean>

    3)测试Bean

    总结:同1中的两个接口实现了同样的结果

3.@PostConstruct和@PreDestroy注解

    1)这两个怎么用呢?具体如下:

// 在LifeCycleBean中添加以下即可
@PostConstruct
public void postConstruct() {
    System.out.println("annotation init ...");
}

@PreDestroy
public void preDestroy() {
    System.out.println("annotation destroy...");
}

    2)beans.xml定义如前,测试代码如前,结果如下所示:

// 结果是空的,好尴尬

    疑问:为什么是空的呢?为什么在main方法中通过容器获取Bean的这种方式没有执行postConstruct()方法和preDestroy()方法呢?

    答疑:我们可以看到这两个是注解类的,我们之前Bean的定义全都是通过xml定义的方式来实现的。说明我们目前的Spring容器还没有辨识注解的能力。

    扩展:在目前的开发项目中,我们一般都是通过注解来自动注入Bean,如果@Controller @Service @Component之类的注解,但是这个有一个前提条件是我们必须要先让Spring有识别注解的能力,这样就需要在beans.xml文件中添加以下内容

<context:annotation-config/>

    3)添加了上述注解之后,我们再运行一次,结果如下:

annotation init ...
InitializingBean init...
xml init...

annotation destroy...
DisposableBean destroy...
xml destroy...

 

4.这些生命周期行为方法的选择

    既然一个Bean的初始化和销毁方法有这么几种方式,那么在实际运用中我们应该如何选择呢?Spring已经给出了相关建议

// init相关建议
It is recommended that you do not use the InitializingBean interface because it unnecessarily couples the code to Spring. Alternatively, use the @PostConstruct annotation or specify a POJO initialization method. In the case of XML-based configuration metadata, you use the init-method attribute to specify the name of the method that has a void no-argument signature. With Java config, you use the initMethod attribute of @Bean
    
// destroy相关建议
It is recommended that you do not use the DisposableBean callback interface because it unnecessarily couples the code to Spring. Alternatively, use the @PreDestroy annotation or specify a generic method that is supported by bean definitions. With XML-based configuration metadata, you use the destroy-method attribute on the <bean/>. With Java config, you use the destroyMethod attribute of @Bean

    总结下来就是:建议在项目中使用@PostConstruct和@PreDestroy,因为InitializingBean和DisposableBean与代码强耦合。如果非Web项目,我们也可以使用<bean>中的init-method和destroy-method

5.生命周期方法的执行顺序

    如果一个Bean这几种生命周期方法都有的话,那么执行顺序应该是怎样的呢?

    Spring同样也给出了答案

Multiple lifecycle mechanisms configured for the same bean, with different initialization methods, are called as follows:
// 初始化方法调用顺序
1.Methods annotated with @PostConstruct
2.afterPropertiesSet() as defined by the InitializingBean callback interface
3.A custom configured init() method

Destroy methods are called in the same order:
// 销毁方法调用顺序
1.Methods annotated with @PreDestroy
2.destroy() as defined by the DisposableBean callback interface
3.A custom configured destroy() method

总结:

    以上三种Bean生命周期管理的方式,我们可以自由选择,一般来说从注解和Spring接口中选择一种,如果我们不想与Spring强耦合,那么可以选择注解方式

参考:

https://docs.spring.io/spring/docs/4.3.23.RELEASE/spring-framework-reference/htmlsingle/ 

代码地址:https://github.com/kldwz/springstudy  

发布了122 篇原创文章 · 获赞 119 · 访问量 12万+

猜你喜欢

转载自blog.csdn.net/qq_26323323/article/details/89790006