六、Spring注解:给Bean指定初始化和销毁方法

容器管理着bean的生命周期,bean的生命周期包含创建—初始化—销毁等一系列过程。
Spring允许我们在Bean 初始化完成后以及销毁前执行特定的操作。基本上有三种可以指定特定操作的方式。

1. initMethod() 与 destroyMethod()

​ 首先声明一个基础的Java类:

public class Car {

    private String name;

     public Car(String name) {
        this.name = name;
        System.out.println("Car...Constructor ");
    }

    public void init(){
        System.out.println("car name:"+name);
        System.out.println("car ... init ...");
    }

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

    // 省略get/set
}

​ 使用XML方式配置Bean的时候,通过 元素的 init-method/destroy-method属性可以指定初始化之后 、销毁之前调用的操作方法。

<bean id="car" class="com.baiding.model.Car" init-method="init" destroy-method="destory">
        <property name="name" value="audi"/>
</bean>

​ 不过在使用@Bean注解声明bean的时候,也可以做出上述XML配置相同的功能,基本实例如下:

声明一个Java配置类,在配置类中使用@Bean注解声明一个组件

@Configuration
public class LifecycleConfig {

    @Bean(initMethod = "init",destroyMethod = "destory")
    public Car car(){
        return new Car("audi");
    }
}

使用测试类测试一下

public class LifecycleTest {

    @Test
    void test01(){
        ApplicationContext ac = new AnnotationConfigApplicationContext(LifecycleConfig.class);
        System.out.println("容器创建完毕...");
    }
}

执行这个测试方法。在这个测试方法中,我们只是创建好了容器。

Car...Constructor 
car name:audi
car ... init ...
容器创建完毕...
car ... destory ...
@Bean 注解默认创建单实例的bean,对于单实例的bean来说:
当对象创建完成,并完成赋值操作之后,开始调用初始化方法 initMethod()
当容器关闭的时候,执行销毁方法 destoryMethod()
对于多实例的bean来说,每次获取bean时都会创建一个实例,容器不会管理这个bean,也就是说容器关闭的时候不会调用多实例bean的销毁方法(只需将bean的@Scope设置为prototype,可以看出容器关闭的时候并没有调用销毁方法)。

2. InitializingBean 与 DisposableBean

​ 还可以让bean实现InitializingBean 接口 定义自身初始化逻辑,实现DisposableBean接口定义销毁逻辑。

改造一下刚开始的Car类:实现上述两个接口

public class Car implements InitializingBean,DisposableBean{

    private String name;

    public Car(String name) {
        this.name = name;
        System.out.println("Car...Constructor ");
    }

    public void initMethod(){
        System.out.println("car name:"+name);
        System.out.println("car ... initMothod ...");
    }

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

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

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

    // 省略get、set
}

配置类和测试类不变,直接看结果:

Car...Constructor 
car...InitializingBean...afterPropertiesSet
car name:audi
car ... initMothod ...
容器创建完毕...
car ...DisposableBean... destory
car ... destoryMethod ...
从结果可以看出,通过实现接口定义自身的初始化或者销毁逻辑,同样是在容器创建完成,bean对象构造好同时赋值成功之后,开始执行初始化方法,在容器关闭之后执行销毁逻辑。

3. @PostConstruct 与 @PreDestroy

​ 可以在指定方法上加上@PostConstruct或者@PreDestroy注解,来指定该方法是在bean初始化之后还是在销毁之前就调用。

​ 改造一下刚开始的Car类:加上两个方法,分别加上两个注解。

public class Car implements InitializingBean,DisposableBean{

    private String name;

    public Car(String name) {
        this.name = name;
        System.out.println("Car...Constructor ");
    }

    public void initMethod(){
        System.out.println("car name:"+name);
        System.out.println("car ... initMothod ...");
    }

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

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

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

    @PostConstruct
    public void postConstruct(){
        System.out.println("car...postConstruct");
    }

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

    // 省略get、set
}

配置类和测试类不变,直接看结果:

Car...Constructor 
car...postConstruct
car...InitializingBean...afterPropertiesSet
car name:audi
car ... initMothod ...
容器创建完毕...
car... preDestroy
car ...DisposableBean... destory
car ... destoryMethod ...
可以看出,@PostConstruct 与 @PreDestroy 这两个注解与上述两种方法功能基本相似,只是在他们同时起作用的时候,执行顺序还是有些规律的。

初始化之后执行: @PostConstruct > InitializingBean > init-method

销毁之前执行:@preDestroy > DisposableBean > destoryMethod

猜你喜欢

转载自blog.csdn.net/liujun03/article/details/81671041