Spring 中容器初始化時呼叫的介面類
在日常開發中難免會經常遇到這樣的應用場景,在專案初始化時執行指定的程式碼實現一些功能,或者在專案啟動後執行一些程式碼實現功能。這個時候就需要用到Spring提供的一些介面、註解了。本文都是以SpringBoot為基礎。
1.Spring容器啟動前執行
1.1介面類InitializingBean
直接在程式碼中實現該介面afterPropertiesSet方法,並在該方法中執行程式碼。
值得注意的是 在該介面執行時Spring 容器是還沒有初始化完成的。在這裡取spring容器中的物件可能會被丟擲空指標異常。
@Component public class TestConfigInitializingBean implements InitializingBean { private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigInitializingBean.class); @Override public void afterPropertiesSet() throws Exception { LOGGER.info("--------------------------------------------"); LOGGER.info("-----正在執行InitializingBean實現類程式碼-----"); LOGGER.info("--------------------------------------------"); } }
1.2 註解實現@PostConstruct
這種方式相對於InitializingBean介面實現要方便一些。直接在需要的方法上新增該註解即可。
這種方式與上面InitializingBean介面一樣都是在spring容器初始化前執行,所有在該註解方法中獲取容器內物件可能存在空指標異常
@Component public class TestPostConstruct { private static final Logger LOGGER = LoggerFactory.getLogger(TestPostConstruct.class); @PostConstruct public void initPostConstruct() { LOGGER.info("--------------------------------------------"); LOGGER.info("-----正在執行@PostConstruct實現類程式碼-----"); LOGGER.info("--------------------------------------------"); } }
2 Spring容器初始化完成後執行
2.1 實現監聽器 ApplicationListener<ApplicationEvent>
關於這個介面,很多人可能會遇到多次執行該方法。其實這是正常現象,我在執行這段程式碼時,被重複呼叫了3次
通過debug除錯觀察發現,3次執行引數ApplicationEvent event都是不同的。
第一次引數內source是AnnotationConfigEmbeddedWebApplicationContext
第二次引數內source是TomcatEmbeddedServletContainer
第三次引數內source是SpringApplication
我個人的理解為springboot web容器載入時觸發該方法一次,springboot自帶tomcat容器初始化時觸發容器一次
第三次是springApplication 建立並初始化Spring上下文時再次觸發該監聽
直接上程式碼
@Component
public class TestConfigApplicationListener implements ApplicationListener<ApplicationEvent> {
private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigApplicationListener.class);
@Override
public void onApplicationEvent(ApplicationEvent event) {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在執行ApplicationListener實現類程式碼-----");
LOGGER.info("--------------------------------------------");
}
}
補充: ApplicationEvent該類是一個監聽事件抽象類,它下面有很多子類。分別實現不同的事件監聽。該監聽器的具體執行時間可根據不同的監聽型別物件(ApplicationEvent子類)在不同的時間執行 專案啟動前、啟動後等,具體每個類的監聽後面的文章在分析。
原理:ApplicationContextAware介面提供了publishEvent方法,實現了Observe(觀察者)設計模式的傳播機制,實現了對bean的傳播。通過ApplicationContextAware把系統中所有ApplicationEvent傳播給所有的ApplicationListener。
2.2 實現介面ApplicationRunner
在程式碼中實現介面的run方法,並在run方法中編寫邏輯程式碼
該方法可以通過@order(value= 數字) 來控制執行順序,順序是依次從小到大執行
@Component
@Order(value = 3)
public class TestConfigApplicationRunner implements ApplicationRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigApplicationRunner.class);
@Override
public void run(ApplicationArguments args) throws Exception {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在執行ApplicationRunner實現類程式碼-----");
LOGGER.info("--------------------------------------------");
}
}
2.2 實現介面CommandLineRunner
CommandLineRunner介面的使用方式與ApplicationRunner介面基本相似,不同的只是方法的引數型別,CommandLineRunner的引數是基本型別,而ApplicationRunner是的引數是ApplicationArguments物件,經過封裝,使用者可對引數進行更多操作
@Component
@Order(value = 2)
public class TestConfigCommandLineRunner implements CommandLineRunner {
private static final Logger LOGGER = LoggerFactory.getLogger(TestConfigCommandLineRunner.class);
@Override
public void run(String... args) throws Exception {
LOGGER.info("--------------------------------------------");
LOGGER.info("-----正在執行CommandLineRunner實現類程式碼-----");
LOGGER.info("--------------------------------------------");
}
}
程式碼最終執行結果日誌:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.10.RELEASE)
2018-09-05 12:20:08.212 INFO 7140 --- [ main] com.port.test.PortTestApp : Starting PortTestApp on DESKTOP-R7GPPNQ with PID 7140 (E:\workSpace\learn-project\port-test\target\classes started by zane in E:\workSpace\learn-project\port-test)
2018-09-05 12:20:08.214 INFO 7140 --- [ main] com.port.test.PortTestApp : No active profile set, falling back to default profiles: default
2018-09-05 12:20:08.255 INFO 7140 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot[email protected]140e5a13: startup date [Wed Sep 05 12:20:08 CST 2018]; root of context hierarchy
2018-09-05 12:20:09.431 INFO 7140 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2018-09-05 12:20:09.443 INFO 7140 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2018-09-05 12:20:09.445 INFO 7140 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.27
2018-09-05 12:20:09.554 INFO 7140 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2018-09-05 12:20:09.554 INFO 7140 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1301 ms
2018-09-05 12:20:09.681 INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2018-09-05 12:20:09.684 INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2018-09-05 12:20:09.685 INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2018-09-05 12:20:09.685 INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2018-09-05 12:20:09.685 INFO 7140 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2018-09-05 12:20:09.733 INFO 7140 --- [ main] c.p.t.config.TestConfigInitializingBean : --------------------------------------------
2018-09-05 12:20:09.733 INFO 7140 --- [ main] c.p.t.config.TestConfigInitializingBean : -----正在執行InitializingBean實現類程式碼-----
2018-09-05 12:20:09.733 INFO 7140 --- [ main] c.p.t.config.TestConfigInitializingBean : --------------------------------------------
2018-09-05 12:20:09.736 INFO 7140 --- [ main] com.port.test.config.TestPostConstruct : --------------------------------------------
2018-09-05 12:20:09.736 INFO 7140 --- [ main] com.port.test.config.TestPostConstruct : -----正在執行@PostConstruct實現類程式碼-----
2018-09-05 12:20:09.736 INFO 7140 --- [ main] com.port.test.config.TestPostConstruct : --------------------------------------------
2018-09-05 12:20:09.969 INFO 7140 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot[email protected]140e5a13: startup date [Wed Sep 05 12:20:08 CST 2018]; root of context hierarchy
2018-09-05 12:20:10.038 INFO 7140 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2018-09-05 12:20:10.039 INFO 7140 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2018-09-05 12:20:10.066 INFO 7140 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.066 INFO 7140 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.098 INFO 7140 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2018-09-05 12:20:10.220 INFO 7140 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2018-09-05 12:20:10.229 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.230 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : -----正在執行ApplicationListener實現類程式碼-----
2018-09-05 12:20:10.230 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.290 INFO 7140 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2018-09-05 12:20:10.291 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.291 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : -----正在執行ApplicationListener實現類程式碼-----
2018-09-05 12:20:10.291 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigCommandLineRunner : --------------------------------------------
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigCommandLineRunner : -----正在執行CommandLineRunner實現類程式碼-----
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigCommandLineRunner : --------------------------------------------
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationRunner : --------------------------------------------
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationRunner : -----正在執行ApplicationRunner實現類程式碼-----
2018-09-05 12:20:10.293 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationRunner : --------------------------------------------
2018-09-05 12:20:10.294 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.294 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : -----正在執行ApplicationListener實現類程式碼-----
2018-09-05 12:20:10.294 INFO 7140 --- [ main] c.p.t.c.TestConfigApplicationListener : --------------------------------------------
2018-09-05 12:20:10.295 INFO 7140 --- [ main] com.port.test.PortTestApp : Started PortTestApp in 2.328 seconds (JVM running for 2.652)
相關推薦
Spring 中容器初始化時呼叫的介面類
在日常開發中難免會經常遇到這樣的應用場景,在專案初始化時執行指定的程式碼實現一些功能,或者在專案啟動後執行一些程式碼實現功能。這個時候就需要用到Spring提供的一些介面、註解了。本文都是以SpringBoot為基礎。 1.Spring容器啟動前執行 1.1介面
Spring中的初始化InitializingBean介面和DisposableBean介面
最近在看關於redis整合的程式碼的時候,配置jedis的擴充套件操作RedisTemplate類,其中有屬性設定jedis連線,忍不住好奇,看了看RedisTemplate的實現。發現RedisTemplate類繼承了RedisAccessor,而RedisAcc
Java 中 HashMap 初始化時賦值
lec SM 解決 道理 test ack 增加 數據結構 解決辦法 1、HashMap 初始化的文藝寫法HashMap 是一種常用的數據結構,一般用來做數據字典或者 Hash 查找的容器。普通青年一般會這麽初始化:HashMap<String, S
03.Spring IoC 容器 - 初始化
itl ret num servlet fontsize eat 圖片 number sources 基本概念 Spring IoC 容器的初始化過程在監聽器 ContextLoaderListener 類中定義。 具體由該類的的 configureAndRefreshWe
Spring中Bean初始化的三種方法
常用的設定方式有以下三種: 通過實現 InitializingBean/DisposableBean 介面來定製初始化之後/銷燬之前的操作方法; 通過 <bean> 元素的 init-method/destroy-method屬性指定初始化之後 /銷燬之前呼叫的
spring中bean初始化過程
在傳統的Java應用中,Bean的生命週期非常簡單。Java的關鍵詞new用來例項化Bean(或許他是非序列化的)。這樣就夠用了。相反,Bean 的生命週期在Spring容器中更加細緻。理解Spring Bean的生命週期非常重要,因為你或許要利用Spring提供的機會來訂製
JAVA中陣列初始化時用new與不用new有區別嗎
不同於String類,String由於實現了常量池 所以new 和不new 有區別:new的話,引用變數指向堆區。不new的話,引用變數指向常量池。對於陣列的定義,初始化時用new與不用new 沒區別,
Spring中bean初始化的三種方式
(1)配置檔案 <!-- 1.構造方法例項化bean --> <bean id="book" class="service."/> <!-- 2.使用靜態工廠方法例項化bean ,由於方法是static,可以通過類名呼
SP2-1503: 無法初始化 Oracle 呼叫介面 SP2-1503: 無法初始化 Oracle 問題的解決辦法
win7 下 cmd 執行 sqlplus 報錯以下錯誤。 SP2-1503: 無法初始化Oracle 呼叫介面 SP2-1503: 無法初始化Oracle 調SP2-0152 解決辦法: 在oracle\product\10.2.0\db_2\BIN 目
Spring原始碼解讀-Spring IoC容器初始化之資源定位
**IoC初始化過程 首先spring IoC容器的初始化,要分成三大部分,BeanDefinition的 Resource定位、載入和註冊三個基本過程。 今天我要說的就是資原始檔的定位,IoC容
Spring中的初始化註解@PostConstruct
配置檔案: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://ww
Mybatis在spring容器中的初始化過程
tsql tor 懶加載 alt onf mes text batis mybatis 由servlet容器調用容器啟動監聽器 spring的applicationContext刷新 實例化所有的單例(非懶加載的) beanNames:所有的單例(非懶加載的)的id,
spring容器初始化bean的過程中的時間週期
知識點介紹 1、 init-method方法,初始化bean的時候執行,可以針對某個具體的bean進行配置。init-method需要在 applicationContext.xml配置文件中bean的定義裡頭寫明。例如:<bean id="TestBean" cla
Java Web系統初始化時從資料庫中載入資料到文字(ibatis,spring)
有一些特殊情況,需要在系統初始化時載入一些配置屬性到本地文字中 web.xml <listener> <listener-class> org.springfra
Golang 引用庫中含有初始化代碼時如何引用
usr nbsp 博文 str 符號 imp oca all 補充 簡單點說吧,要在引用庫前加‘_‘符號 給出示例 //foo.go // /usr/local/go/pkg/src/foo/foo.go package foo import "fmt" type Foo
Spring源碼分析總結(一)-IOC容器初始化
Spring源碼分析總結一、IOC容器的初始化過程 IOC容器的初始化是由refresh()方法啟動。經常使用的ApplicationContext 有:ClassPathXmlApplicationContext和FileSystemXmlApplicationContext、XmlWebApp
spring原始碼學習之路---IOC容器初始化要義之bean定義載入(四)
上章說到要帶各位去看看bean定義載入的要義,其實就是loadBeanDefinitions這個方法的具體實現步驟,下面我們跟隨這個方法去看下它到底是如何載入bean定義的。 上面是我擷取的實現了loadBeanDefinitions的類級別截圖,loadBeanDefinit
spring原始碼學習之路---深度分析IOC容器初始化過程(三)
分析FileSystemXmlApplicationContext的建構函式,到底都做了什麼,導致IOC容器初始化成功。 public FileSystemXmlApplicationContext(String[] configLocations, boolean ref
spring容器初始化bean之後或銷燬bean之前,能做的操作
通過 <bean> 標籤 init-method 初始化bean之後呼叫的方法 destroy-method 銷燬bean之前呼叫的操作方法 <bean id="initQuartzJob" class="com.upinc
linux3.3核心驅動初始化時具體呼叫的函式
system.map描述了程式碼具體的呼叫過程,對照這個過程,通過source-insight軟體搜尋到相應的初始化函式,整理如下: c0599ba4 t __initcall_init_static_idmapearly c0599ba4 T __initcall_start