淺談SpringBoot中的Bean初始化方法?@PostConstruct
注解說明
- 使用注解: @PostConstruct
- 效果:在Bean初始化之后(構(gòu)造方法和@Autowired之后)執(zhí)行指定操作。經(jīng)常用在將構(gòu)造方法中的動(dòng)作延遲。
- 備注:Bean初始化時(shí)候的執(zhí)行順序: 構(gòu)造方法 -> @Autowired -> @PostConstruct
代碼示例
注解示例
@Component public class PostConstructTest1 { @Autowired PostConstructTest2 postConstructTest2; public PostConstructTest1() { // postConstructTest2.hello(); } @PostConstruct public void init() { // some init function } }
在Bean的初始化操作中,有時(shí)候會遇到調(diào)用其他Bean的時(shí)候報(bào)空指針錯(cuò)誤。這時(shí)候就可以將調(diào)用另一個(gè)Bean的方法這個(gè)操作放到@PostConstruct注解的方法中,將其延遲執(zhí)行。
錯(cuò)誤示例
@Component public class PostConstructTest1 { @Autowired PostConstructTest2 postConstructTest2; public PostConstructTest1() { postConstructTest2.hello(); } }
@Component public class PostConstructTest2 { public void hello() { System.out.println("hello, i am PostConstructTest2"); } }
正確示例
@Component public class PostConstructTest1 { @Autowired PostConstructTest2 postConstructTest2; public PostConstructTest1() { postConstructTest2.hello(); } }
@Component public class PostConstructTest1 { @Autowired PostConstructTest2 postConstructTest2; public PostConstructTest1() { // postConstructTest2.hello(); } @PostConstruct public void init() { postConstructTest2.hello(); } }
SpringBoot @PostConstruct雖好,也要慎用
做過SpringBoot開發(fā)的話,肯定對@PostConstruct比較熟悉。在一個(gè)Bean組件中,標(biāo)記了@PostConstruct的方法會在Bean構(gòu)造完成后自動(dòng)執(zhí)行方法的邏輯。
1 問題的產(chǎn)生
先說下SpringBoot中Bean的加載過程,簡單點(diǎn)說就是SpringBoot會把標(biāo)記了Bean相關(guān)注解(例如@Component、@Service、@Repository等)的類或接口自動(dòng)初始化全局的單一實(shí)例,如果標(biāo)記了初始化順序會按照用戶標(biāo)記的順序,否則按照默認(rèn)順序初始化。在初始化的過程中,執(zhí)行完一個(gè)Bean的構(gòu)造方法后會執(zhí)行該Bean的@PostConstruct方法(如果有),然后初始化下一個(gè)Bean。
那么: 如果@PostConstruct方法內(nèi)的邏輯處理時(shí)間較長,就會增加SpringBoot應(yīng)用初始化Bean的時(shí)間,進(jìn)而增加應(yīng)用啟動(dòng)的時(shí)間。因?yàn)橹挥性贐ean初始化完成后,SpringBoot應(yīng)用才會打開端口提供服務(wù),所以在此之前,應(yīng)用不可訪問。
2 案例模擬
為了模擬上面說的情況,在SpringBoot項(xiàng)目中建兩個(gè)組件類ComponentOne和ComponentTwo。耗時(shí)的初始化邏輯放在ComponentOne中,并設(shè)置ComponentOne的初始化順序在ComponentTwo之前。完整代碼如下:
@Component @Order(Ordered.HIGHEST_PRECEDENCE) public class ComponentOne { private Logger logger = LoggerFactory.getLogger(this.getClass()); public ComponentOne() { this.logger.info("ComponentOne 初始化完成"); } @PostConstruct public void init() { this.logger.info("ComponentOne 模擬耗時(shí)邏輯開始"); try { //這里休眠5秒模擬耗時(shí)邏輯 Thread.sleep(1000 * 5); } catch (InterruptedException e) { logger.info("模擬邏輯耗時(shí)失敗", e); } this.logger.info("ComponentOne 模擬耗時(shí)邏輯完成"); } }
@Component @Order(Ordered.HIGHEST_PRECEDENCE + 1) public class ComponentTwo { private Logger logger = LoggerFactory.getLogger(this.getClass()); public ComponentTwo() { this.logger.info("ComponentTwo 初始化完成"); } @PostConstruct public void init() { this.logger.info("ComponentTwo 初始化完成后處理"); } }
啟動(dòng)應(yīng)用,初始化部分日志如下:
3 總結(jié)
所以,如果應(yīng)用有一些初始化操作,有以下幾點(diǎn)建議:
- 輕量的邏輯可放在Bean的@PostConstruct方法中
- 耗時(shí)長的邏輯如果放在@PostConstruct方法中,可使用獨(dú)立線程執(zhí)行
- 初始化操作放在CommandLineRunner或ApplicationRunner的實(shí)現(xiàn)組件中
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot @PostConstruct原理用法解析
- SpringBoot @PostConstruct和@PreDestroy的使用說明
- springboot?@PostConstruct無效的解決
- SpringBoot使用@PostConstruct注解導(dǎo)入配置方式
- SpringBoot中的@PostConstruct注解詳細(xì)解析
- springboot啟動(dòng)加載CommandLineRunner @PostConstruct問題
- SpringBoot中@PostConstruct 注解的實(shí)現(xiàn)
- springboot中@PostConstruct注解使用小結(jié)
相關(guān)文章
Java 數(shù)據(jù)結(jié)構(gòu)鏈表操作實(shí)現(xiàn)代碼
這篇文章主要介紹了Java 數(shù)據(jù)結(jié)構(gòu)鏈表操作的相關(guān)資料,并附實(shí)例代碼,需要的朋友可以參考下2016-10-10java中靜態(tài)導(dǎo)入機(jī)制用法實(shí)例詳解
這篇文章主要介紹了java中靜態(tài)導(dǎo)入機(jī)制用法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-07-07Java由淺入深細(xì)數(shù)數(shù)組的操作上
數(shù)組對于每一門編程語言來說都是重要的數(shù)據(jù)結(jié)構(gòu)之一,當(dāng)然不同語言對數(shù)組的實(shí)現(xiàn)及處理也不盡相同。Java?語言中提供的數(shù)組是用來存儲固定大小的同類型元素2022-04-04StringUtils工具包中字符串非空判斷isNotEmpty和isNotBlank的區(qū)別
今天小編就為大家分享一篇關(guān)于StringUtils工具包中字符串非空判斷isNotEmpty和isNotBlank的區(qū)別,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2018-12-12使用Mybatis遇到的there is no getter異常
這篇文章主要介紹了使用Mybatis遇到的there is no getter異常,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-09-09