@PostConstruct注解
@PostConstruct注解好多人以為是Spring提供的。其實是Java自己的注解。我們來看下@PostConstruct注解的源碼,如下所示。
package javax.annotation; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Documented @Retention (RUNTIME) @Target(METHOD) public @interface PostConstruct { }
從源碼可以看出,@PostConstruct注解是Java中的注解,並不是Spring提供的注解。
@PostConstruct注解被用來修飾一個非靜態的void()方法。被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,並且只會被服務器執行一次。PostConstruct在構造函數之后執行,init()方法之前執行。
通常我們會是在Spring框架中使用到@PostConstruct注解,該注解的方法在整個Bean初始化中的執行順序:
Constructor(構造方法) -> @Autowired(依賴注入) -> @PostConstruct(注釋的方法)。
@PreDestroy注解
@PreDestroy注解同樣是Java提供的,看下源碼,如下所示。
package javax.annotation; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.*; @Documented @Retention (RUNTIME) @Target(METHOD) public @interface PreDestroy { }
被@PreDestroy修飾的方法會在服務器卸載Servlet的時候運行,並且只會被服務器調用一次,類似於Servlet的destroy()方法。被@PreDestroy修飾的方法會在destroy()方法之后運行,在Servlet被徹底卸載之前。執行順序如下所示。
調用destroy()方法->@PreDestroy->destroy()方法->bean銷毀。
總結:@PostConstruct,@PreDestroy是Java規范JSR-250引入的注解,定義了對象的創建和銷毀工作,同一期規范中還有注解@Resource,Spring也支持了這些注解。
案例程序
對@PostConstruct注解和@PreDestroy注解有了簡單的了解之后,接下來,我們就寫一個簡單的程序來加深對這兩個注解的理解。
我們創建一個Cat類,如下所示。
import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; public class Cat { public Cat(){ System.out.println("Cat類的構造方法..."); } public void init(){ System.out.println("Cat的init()方法..."); } @PostConstruct public void postConstruct(){ System.out.println("Cat的postConstruct()方法..."); } @PreDestroy public void preDestroy(){ System.out.println("Cat的preDestroy()方法..."); } public void destroy(){ System.out.println("Cat的destroy()方法..."); } }
可以看到,在Cat類中,我們提供了構造方法,init()方法、destroy()方法,使用 @PostConstruct注解標注的postConstruct()方法和只用@PreDestroy注解標注的preDestroy()方法。接下來,我們在AnimalConfig類中使用@Bean注解將Cat類注冊到Spring容器中,如下所示。
@Bean(initMethod = "init", destroyMethod = "destroy") public Cat cat(){ return new Cat(); }
接下來,在BeanLifeCircleTest類中新建testBeanLifeCircle04()方法進行測試,如下所示。
@Test public void testBeanLifeCircle04(){ //創建IOC容器 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnimalConfig.class); //關閉IOC容器 context.close(); }
運行BeanLifeCircleTest類中的testBeanLifeCircle04()方法,輸出的結果信息如下所示。
Cat類的構造方法...
Cat的postConstruct()方法...
Cat的init()方法...
Cat的preDestroy()方法...
Cat的destroy()方法...
從輸出的結果信息中,可以看出執行的順序是:構造方法 -> @PostConstruct -> init()方法 -> @PreDestroy -> destroy()方法。