spring学习(二十四)--@PostConstruct和@PreDestroy

Posted on 2019-11-07 16:05  GLLegolas  阅读(213)  评论(0编辑  收藏  举报

@PostConstruct和@PreDestroy,这两个注解被用来修饰一个非静态的void()方法。

 

@PostConstruct

@PostConstruct在构造方法和init方法(如果有的话)之间得到调用,且只会执行一次。其实从依赖注入的字面意思就可以知道,要将对象A注入到对象B,那么首先就必须得生成对象B和对象A,才能执行注入。所以,如果一个类B中有个成员变量A被@Autowried注解注入,那么@Autowired注入是发生在B的构造方法执行完之后的。 如果想在生成对象B时完成某些初始化操作,而偏偏这些初始化操作又依赖于A注入,那么就无法在构造函数中实现。可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖A注入完成后被自动调用,而且@PostConstruct方法只会被调用一次。

@PreDestroy

@PreDestroy注解的方法在destory()方法调用后得到执行。

 

例子:

LittleBall.java

package serviceImpl;

import interfaces.GirlsInterface;

public class LittleBall implements GirlsInterface{

    public String girlsName;
    
    /**
     * 重写构造函数,输出信息,来确定bean初始化时间
     */
    public LittleBall(){
        System.out.println("Hello, I am little ball! I am very beautiful!");
    }
    
    public String getGirlsName(){
        return girlsName;
    }
    public void setGirlsName(String girlsName) {
        this.girlsName = girlsName;
    }
}

PostConstructAnnotion.java
package springAnnotions;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;
import serviceImpl.LittleBall;

/**
 * 其实从依赖注入的字面意思就可以知道,要将对象A注入到对象B,那么首先就必须得生成对象B和对象A,才能执行注入。
 * 所以,如果一个类B中有个成员变量A被@Autowried注解注入,那么@Autowired注入是发生在B的构造方法执行完之后的。
 * 如果想在生成对象B时完成某些初始化操作,而偏偏这些初始化操作又依赖于A注入,那么就无法在构造函数中实现。
 * 可以使用@PostConstruct注解一个方法来完成初始化,@PostConstruct注解的方法将会在依赖A注入完成后被自动调用
 * 而且@PostConstruct方法只会被调用一次
 * @author qiaozhong
 */

@Component
public class PostConstructAnnotion {
    
    @Autowired
    private LittleBall littleBall;
    
    public PostConstructAnnotion() {
        System.out.println("我是PostConstructAnnotion的构造函数,是在PostConstructAnnotion初始化bean的时候被调用执行的");
    }
    
    @PostConstruct
    public void postConstruct(){
        System.out.println("@PostConstruct注解是在容器启动时候,在LittleBall被注入之后调用执行的,而且只会执行一次,littleBall=" + littleBall);
    }
    
    @PreDestroy
    public void preDestroy(){
        System.out.println("@preDestroy注解是在bean销毁时,在执行destroy()方法之后执行的");
    }
    
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("springConfig/spring-all.xml");
        PostConstructAnnotion postConstructAnnotion = (PostConstructAnnotion)context.getBean("postConstructAnnotion");
        context.destroy();
    }
}

执行main函数结果:

我是PostConstructAnnotion的构造函数,是在PostConstructAnnotion初始化bean的时候被调用执行的
Hello, I am little ball! I am very beautiful!
@PostConstruct注解是在容器启动时候,在LittleBall被注入之后调用执行的,而且只会执行一次,littleBall=serviceImpl.LittleBall@5136d012
2019-11-07 16:00:39.610 [main] org.springframework.context.support.ClassPathXmlApplicationContext INFO - Closing org.springframework.context.support.ClassPathXmlApplicationContext@6bf2d08e: startup date [Thu Nov 07 16:00:38 CST 2019]; root of context hierarchy
@preDestroy注解是在bean销毁时,在执行destroy()方法之后执行的

1、先执行了PostConstructAnnotion的构造函数,又执行了LittleBall的构造函数。在LittleBall注入到PostConstructAnnotion之后,执行了@PostConstruct注解的方法postConstruct()。

2、在执行context.destroy()销毁bean的时候,调用了PostConstructAnnotion的destroy()方法,然后调用了@PreDestroy注解的方法preDestroy()。