【String註解驅動開發】你瞭解@PostConstruct註解和@PreDestroy註解嗎?
寫在前面
在之前的文章中,我們介紹瞭如何使用@Bean註解指定初始化和銷燬的方法,小夥伴們可以參見《【Spring註解驅動開發】如何使用@Bean註解指定初始化和銷燬的方法?看這一篇就夠了!!》,也介紹了使用InitializingBean和DisposableBean來處理bean的初始化和銷燬,小夥伴們可以參見《【Spring註解驅動開發】Spring中的InitializingBean和DisposableBean,你真的瞭解嗎?》。除此之外,在JDK中也提供了兩個註解能夠在bean載入到Spring容器之後執行和在bean銷燬之前執行,今天,我們就一起來看看這兩個註解的用法。
專案工程原始碼已經提交到GitHub:
https://github.com/sunshinelyz/spring-annotation
@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類,如下所示。
package io.mykit.spring.plugins.register.bean;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author binghe
* @version 1.0.0
* @description 測試@PostConstruct註解和@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()方法。
好了,咱們今天就聊到這兒吧!別忘了給個在看和轉發,讓更多的人看到,一起學習一起進步!!
專案工程原始碼已經提交到GitHub:https://github.com/sunshinelyz/spring-annotation
寫在最後
如果覺得文章對你有點幫助,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習Spring註解驅動開發。公眾號回覆“spring註解”關鍵字,領取Spring註解驅動開發核心知識圖,讓Spring註解驅動開發不再迷茫。