【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註解驅動開發不再迷茫。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

新北清潔公司,居家、辦公、裝潢細清專業服務

※別再煩惱如何寫文案,掌握八大原則!

※教你寫出一流的銷售文案?

※超省錢租車方案