springboot 項(xiàng)目容器啟動(dòng)后如何自動(dòng)執(zhí)行指定方法
springboot 項(xiàng)目容器啟動(dòng)后自動(dòng)執(zhí)行指定
我們需要寫(xiě)一個(gè)class去讓它實(shí)現(xiàn)ApplicationRunner,然后重寫(xiě)它的run方法就行了,注意類加上@Component注解

注意:這個(gè)class需要寫(xiě)在和Application啟動(dòng)類的同級(jí)目錄或者子級(jí)目錄下,否則不生效。
代碼:
package com.qq.weixin;
import lombok.extern.slf4j.Slf4j;
import org.joda.time.DateTime;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/**
* @author XuYangWei
* @Date 2021/1/22 8:56
*/
@Slf4j
@Component
public class TestRuner implements ApplicationRunner {
@Override
public void run(ApplicationArguments applicationArguments) throws Exception {
log.info("我是Spring容器啟動(dòng)后立即執(zhí)行的方法,當(dāng)前時(shí)間:"+ DateTime.now().toString("yyyy-MM-dd HH:mm:ss"));
}
}
springboot 容器及啟動(dòng)過(guò)程
SpringBoot會(huì)啟動(dòng)兩個(gè)容器,即父子容器
- 父容器(Spring容器):AnnotationConfigWebApplicationContex
- 子容器(SpringMVC容器):AnnotationConfigEmbeddedWebApplicationContex
思考幾個(gè)問(wèn)題:
問(wèn)題1:為什么要啟動(dòng)父子兩個(gè)容器?
在Spring整體框架的核心概念中,容器是核心思想,而在一個(gè)項(xiàng)目中,容器不一定只有一個(gè),Spring中可以包括多個(gè)容器,使用上下層關(guān)系來(lái)管理容器可以解決公共屬性抽取的問(wèn)題,即將公共的屬性放到父容器中,對(duì)其各個(gè)子容器均可見(jiàn),實(shí)現(xiàn)了復(fù)用功能,注意子容器對(duì)父容器是不可見(jiàn)的。
問(wèn)題2:在什么時(shí)候啟動(dòng)父容器?
準(zhǔn)備環(huán)境變量,即執(zhí)行prepareEnvironment方法時(shí),發(fā)布ApplicationEnvironmentPreparedEvent事件,BootstrapApplicationListener監(jiān)聽(tīng)器收到該事件,會(huì)初始化父容器
問(wèn)題3:父容器和子容器的區(qū)別?
1.子容器中會(huì)創(chuàng)建植入的tomcat容器類,用來(lái)管理tomcat服務(wù),父容器沒(méi)有
2.父容器管理的bean集合是spring框架內(nèi)置的一些bean,子容器管理的bean集合是我們業(yè)務(wù)定義的bean以及spring框架內(nèi)置的bean
問(wèn)題4:怎么保證父容器啟動(dòng)過(guò)程中
執(zhí)行prepareEnvironment方法時(shí),BootstrapApplicationListener監(jiān)聽(tīng)器不再重復(fù)執(zhí)行?
父容器初始化完成后,會(huì)在webEnvironment屬性中加入bootstrap屬性標(biāo)識(shí),這樣就可以根據(jù)該標(biāo)識(shí)來(lái)判斷是否需要執(zhí)行了
問(wèn)題5:容器實(shí)際通過(guò)什么來(lái)管理bean
容器通過(guò)beanFactory來(lái)管理對(duì)象,父子容器都會(huì)各持有一個(gè)DefaultListableBeanFactory,即父子容器都會(huì)管理各自的bean。
子容器啟動(dòng)流程:
1.執(zhí)行初始化:初始化webEnvironment以及l(fā)isteners
2.發(fā)布容器啟動(dòng)事件
3.在執(zhí)行prepareEnvironment步驟時(shí),發(fā)布ApplicationEnvironmentPreparedEvent事件,BootstrapApplicationListener監(jiān)聽(tīng)器收到該事件,會(huì)再次調(diào)用SpringApplication
- 初始化和run方法(初始化父容器的步驟類似子容器)
4.創(chuàng)建context,通過(guò)判斷webEnvironment標(biāo)識(shí),這時(shí)為true,創(chuàng)建AnnotationConfigEmbeddedWebApplicationContext實(shí)例
5.執(zhí)行refreshContext,比較核心的方法,詳細(xì)說(shuō)一下:
- 獲取bean工廠,即創(chuàng)建DefaultListableBeanFactory實(shí)例
- 為bean工廠賦一些基礎(chǔ)屬性,主要有類加載器
- 為bean工廠注冊(cè)WebApplicationContextServletContextAwareProcessor,一個(gè)BeanPostProcessor,主要用于獲取ServletContext
- 執(zhí)行beanFactoryPostProcessor,遞歸處理,主要用于掃描@CompontScan、@Import、@ImportSource等注解的類,首先注冊(cè)bean元數(shù)據(jù)到工廠,然后可以修改bean工廠
- 實(shí)例化BeanPostProcessor類并注冊(cè)到bean工廠單例列表中
- 實(shí)例化消息通知類并注冊(cè)到bean工廠單例列表中
- 調(diào)用onRefresh方法,初始化一個(gè)植入的tomcat容器
- 注冊(cè)監(jiān)聽(tīng)器到消息通知器中,區(qū)分為兩類:一、從系統(tǒng)配置中加載的監(jiān)聽(tīng)器(已實(shí)例化) 二、已注冊(cè)但還未實(shí)例化的監(jiān)聽(tīng)器
- 實(shí)例化注冊(cè)表中的所有bean,創(chuàng)建bean的過(guò)程中會(huì)執(zhí)行bean的初始化操作,會(huì)執(zhí)行BeanPostProcessor、afterPropertiesSet、初始化方法等等
- 調(diào)用finishRefresh,啟動(dòng)所有bean,發(fā)布ContextRefreshed事件
6.執(zhí)行afterRefresh,調(diào)用實(shí)現(xiàn)了ApplicationRunner/CommandLineRunner接口的bean run方法
7.發(fā)布ApplicationReadyEvent事件
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
- SpringBoot工程啟動(dòng)時(shí)自動(dòng)執(zhí)行任務(wù)實(shí)現(xiàn)方式
- SpringBoot啟動(dòng)后自動(dòng)執(zhí)行方法的各種方式對(duì)比
- SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行特定代碼的完整指南
- SpringBoot啟動(dòng)后自動(dòng)執(zhí)行初始化任務(wù)的五種方法
- SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行指定方法的幾種實(shí)現(xiàn)方式
- SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行代碼的幾種實(shí)現(xiàn)方式
- SpringBoot啟動(dòng)時(shí)自動(dòng)執(zhí)行sql腳本的方法步驟
- springBoot啟動(dòng)時(shí)讓方法自動(dòng)執(zhí)行的幾種實(shí)現(xiàn)方式
- SpringBoot 啟動(dòng)時(shí)自動(dòng)執(zhí)行代碼的幾種方式講解
相關(guān)文章
Spring?Boot?集成并開(kāi)發(fā)?Sa-token示例詳解
Sa-token是一款高可用的權(quán)限認(rèn)證框架,他帶我們用最簡(jiǎn)化的配置完成用?spring?security?需要進(jìn)行大量配置的才能完成的工作,這篇文章主要介紹了Spring?Boot?集成并開(kāi)發(fā)?Sa-token,需要的朋友可以參考下2023-06-06
Java的四種常見(jiàn)線程池及Scheduled定時(shí)線程池實(shí)現(xiàn)詳解
這篇文章主要介紹了Java的四種常見(jiàn)線程池及Scheduled定時(shí)線程池實(shí)現(xiàn)詳解,在Java中,我們可以通過(guò)Executors類來(lái)創(chuàng)建ScheduledThreadPool,Executors類提供了幾個(gè)靜態(tài)方法來(lái)創(chuàng)建不同類型的線程池,包括ScheduledThreadPool,需要的朋友可以參考下2023-09-09
springboot 熱啟動(dòng)的過(guò)程圖解
這篇文章主要介紹了springboot 熱啟動(dòng)的過(guò)程圖解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-10-10
Java判斷object對(duì)象為空(包括null ,““)的方法
這篇文章主要介紹了Java判斷對(duì)象是否為空(包括null ,“”)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-12-12

