@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()。