SpringBoot @PostConstruct和@PreDestroy的使用說明
1. @PostConstruct
1.1 概述
@PostConstruct標(biāo)記在方法上,在當(dāng)前類的實例加入到容器之前,會先執(zhí)行@PostConstruct標(biāo)記的方法。它的執(zhí)行順序是這樣的:
- 先執(zhí)行當(dāng)前類的構(gòu)造函數(shù)
- 然后執(zhí)行@Autowired標(biāo)記對象的初始化
- 最后執(zhí)行@PostConstruct標(biāo)記的方法
- 如果沒有拋出異常,則該對象加入Spring管理容器
1.2 驗證執(zhí)行順序
創(chuàng)建一個空的Spring Boot項目,這步不演示了
創(chuàng)建TestComponent
@Component public class TestComponent { public TestComponent(){ System.out.println("TestComponent 構(gòu)造函數(shù)"); } @PostConstruct public void init(){ System.out.println("TestComponent PostConstruct"); } }
創(chuàng)建MyService
public interface MyService { void Hello(String name); }
創(chuàng)建MyServiceImpl
@Service public class MyServiceImpl implements MyService { public MyServiceImpl(){ System.out.println("MyServiceImpl 構(gòu)造函數(shù)"); } @PostConstruct public void init(){ System.out.println("MyServiceImpl PostConstruct"); } @Override public void Hello(String name) { System.out.println("Hello " + name); } }
運行項目,看下輸出結(jié)果。
TestComponent和MyServiceImpl分別獨自初始化,構(gòu)造函數(shù)優(yōu)先執(zhí)行
請記住這個執(zhí)行順序
TestComponent 構(gòu)造函數(shù)
TestComponent PostConstruct
MyServiceImpl 構(gòu)造函數(shù)
MyServiceImpl PostConstruct
還沒完,改一下TestComponent,加入引用MyService
@Autowired private MyService myService;
再執(zhí)行一下,看看結(jié)果有什么變化
TestComponent 構(gòu)造函數(shù)
MyServiceImpl 構(gòu)造函數(shù)
MyServiceImpl PostConstruct
TestComponent PostConstruct
MyServiceImpl執(zhí)行順序往前移動了,證明@Autowired順序在@PostConstruct之前
因此,如果要在TestComponent初始化的時候調(diào)用MyService方法,要寫在@PostConstruct內(nèi)部,不能在構(gòu)造函數(shù)處理(這時候MyServiceImpl還沒初始化,會拋出空指針異常)
@Component public class TestComponent { @Autowired private MyService myService; public TestComponent(){ System.out.println("TestComponent 構(gòu)造函數(shù)"); //寫在這里必定拋出異常,此時 myService == null //myService.Hello("張三"); } @PostConstruct public void init(){ System.out.println("TestComponent PostConstruct"); //在這里調(diào)用MySerice方法才正確 myService.Hello("張三"); } }
2. @PreDestroy
首先,來看下Java Doc對這個注解的說明
1: 在對象實例被容器移除的時候,會回調(diào)調(diào)用@PreDestroy標(biāo)記的方法
2: 通常用來釋放該實例占用的資源
修改上面的TestComponent代碼,加上@PreDestroy代碼
@PreDestroy public void destroy(){ System.out.println("TestComponent 對象被銷毀了"); }
修改Application main方法,啟動10秒后退出程序
@SpringBootApplication public class AnnotationTestApplication { public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(AnnotationTestApplication.class, args); try { Thread.sleep(10 * 1000); } catch (InterruptedException e) { e.printStackTrace(); } ctx.close(); } }
啟動程序,查看輸出信息
程序退出時會銷毀對象,所以會觸發(fā)我們剛寫的@PreDestroy方法,測試通過。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java之Timer和TimerTask簡單demo(分享)
下面小編就為大家?guī)硪黄猨ava之Timer和TimerTask簡單demo(分享)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2016-12-12Java如何使用httpclient檢測url狀態(tài)及鏈接是否能打開
這篇文章主要介紹了Java如何使用httpclient檢測url狀態(tài)及鏈接是否能打開,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09Spring Boot啟動時調(diào)用自己的非web邏輯
在spring Boot中,有些代碼是WEB功能,例如API等,但是有些邏輯是非WEB,啟動時就要調(diào)用并持續(xù)運行的,該如何加載自己的非WEB邏輯呢,下面通過實例代碼給大家講解,一起看看吧2017-07-07Java 可視化垃圾回收_動力節(jié)點Java學(xué)院整理
Ben Evans是一名資深培訓(xùn)師兼顧問,他在演講可視化垃圾回收中從基礎(chǔ)談起討論了垃圾回收。以下是對其演講的簡短總結(jié)。感興趣的朋友一起學(xué)習(xí)吧2017-05-05