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

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

