Spring 容器中的 Bean 是有生命週期的,Bean 的生命週期是指 Bean 建立----> 初始化----> 銷燬 的過程,而且 Spring 容許 Bean 在初始化完成後以及銷燬前執行特定的操做。 下面是經常使用的三種指定特定操做的方法:java
InitDestroyAnnotationBeanPostProcessor
後置處理器來實現的。這幾種配置方式,執行順序是怎樣的呢?咱們經過例子來研究下:git
Bean的列子類:InitBeanAndDestroyBean.javagithub
package com.chenfeng.xiaolyuh.entity; import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; public class InitBeanAndDestroyBean implements InitializingBean, DisposableBean { public String say() { return "Hello!" + this.getClass().getName(); } public InitBeanAndDestroyBean() { System.out.println("執行InitBeanAndDestroyBean構造方法"); } @Override public void destroy() throws Exception { System.out.println("接口-執行InitBeanAndDestroyBeanTest:destroy方法"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("接口-執行InitBeanAndDestroyBeanTest:afterPropertiesSet方法"); } @PostConstruct public void postConstructstroy() { System.out.println("註解-執行InitBeanAndDestroyBeanTest:preDestroy方法"); } @PreDestroy public void preDestroy() { System.out.println("註解--執行InitBeanAndDestroyBeanTest:preDestroy方法"); } public void initMethod() { System.out.println("XML配置-執行InitBeanAndDestroyBeanTest:init-method方法"); } public void destroyMethod() { System.out.println("XML配置-執行InitBeanAndDestroyBeanTest:destroy-method方法"); } }
Spring配置類MyConfig.javaspring
@Configuration // 聲明成配置文件 @ComponentScan("com.chenfeng.xiaolyuh") // 掃描包 public class MyConfig { // 測試Bean的幾種初始化和銷燬方式,和執行順序 @Bean(initMethod="initMethod", destroyMethod="destroyMethod") public InitBeanAndDestroyBean initBeanAndDestroyBean() { return new InitBeanAndDestroyBean(); } }
測試類SpringIocTest.java緩存
public class SpringIocTest { // 使用容器 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class, CatEntity.class); @Test public void contextTest() { // 測試Bean的三種初始化、銷燬方式和執行順序 System.out.println(context.getBean(InitBeanAndDestroyBean.class)); } @After public void closeContext() { context.close(); } }
打印結果:框架
執行InitBeanAndDestroyBean構造方法 20:46:58.845 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Found init method on class [com.xiaolyuh.init.destory.InitBeanAndDestroyBean]: public void com.xiaolyuh.init.destory.InitBeanAndDestroyBean.postConstructstroy() 20:46:58.846 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Found destroy method on class [com.xiaolyuh.init.destory.InitBeanAndDestroyBean]: public void com.xiaolyuh.init.destory.InitBeanAndDestroyBean.preDestroy() 20:46:58.846 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Registered init method on class [com.xiaolyuh.init.destory.InitBeanAndDestroyBean]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@318a3b24 20:46:58.846 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Registered destroy method on class [com.xiaolyuh.init.destory.InitBeanAndDestroyBean]: org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement@a27dd7d7 20:46:58.847 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Eagerly caching bean 'initBeanAndDestroyBean' to allow for resolving potential circular references 後置處理器-執行:postProcessBeforeInitialization 方法 處理:initBeanAndDestroyBean 20:46:58.850 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Invoking init method on bean 'initBeanAndDestroyBean': public void com.xiaolyuh.init.destory.InitBeanAndDestroyBean.postConstructstroy() 註解-執行InitBeanAndDestroyBeanTest:preDestroy方法 20:46:58.850 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking afterPropertiesSet() on bean with name 'initBeanAndDestroyBean' 接口-執行InitBeanAndDestroyBeanTest:afterPropertiesSet方法 20:46:58.851 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Invoking init method 'initMethod' on bean with name 'initBeanAndDestroyBean' XML配置-執行InitBeanAndDestroyBeanTest:init-method方法 後置處理器-執行 執行:postProcessAfterInitialization 方法 處理:initBeanAndDestroyBean 20:46:58.851 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Finished creating instance of bean 'initBeanAndDestroyBean' 20:46:58.851 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'org.springframework.context.event.internalEventListenerFactory' 20:46:58.883 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Unable to locate LifecycleProcessor with name 'lifecycleProcessor': using default [org.springframework.context.support.DefaultLifecycleProcessor@1838ccb8] 20:46:58.883 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor' 20:46:58.885 [main] DEBUG org.springframework.core.env.PropertySourcesPropertyResolver - Could not find key 'spring.liveBeansView.mbeanDomain' in any property source IOC容器完成初始化----> 打印 Spring 容器中的Bean 開始 org.springframework.context.annotation.internalConfigurationAnnotationProcessor org.springframework.context.annotation.internalAutowiredAnnotationProcessor org.springframework.context.annotation.internalRequiredAnnotationProcessor org.springframework.context.annotation.internalCommonAnnotationProcessor org.springframework.context.event.internalEventListenerProcessor org.springframework.context.event.internalEventListenerFactory myConfig initBeanBeanPostProcessor initBeanAndDestroyBean 打印 Spring 容器中的Bean 結束 20:46:58.990 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'initBeanAndDestroyBean' com.xiaolyuh.init.destory.InitBeanAndDestroyBean@5ba88be8 20:46:58.991 [main] INFO org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5af97850: startup date [Mon Aug 26 20:46:58 CST 2019]; root of context hierarchy 20:46:58.991 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Returning cached instance of singleton bean 'lifecycleProcessor' 20:46:58.992 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@78691363: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,myConfig,initBeanBeanPostProcessor,initBeanAndDestroyBean]; root of factory hierarchy 20:46:58.992 [main] DEBUG org.springframework.context.annotation.CommonAnnotationBeanPostProcessor - Invoking destroy method on bean 'initBeanAndDestroyBean': public void com.xiaolyuh.init.destory.InitBeanAndDestroyBean.preDestroy() 註解--執行InitBeanAndDestroyBeanTest:preDestroy方法 20:46:58.992 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy() on bean with name 'initBeanAndDestroyBean' 接口-執行InitBeanAndDestroyBeanTest:destroy方法 20:46:58.993 [main] DEBUG org.springframework.beans.factory.support.DisposableBeanAdapter - Invoking destroy method 'destroyMethod' on bean with name 'initBeanAndDestroyBean' XML配置-執行InitBeanAndDestroyBeanTest:destroy-method方法 關閉IOC容器---->
從執行結果能夠看出: ide
若是Bean不是單例的,那麼Spring不會去管理Bean,Spring 容器中只會存一個Bean標示。Bean的建立和初始化是在獲取Bean的時候發生,而且在再容器關閉時不會調用Bean的銷燬方法。非單例狀況下,Bean的銷燬是依靠GC。spring-boot
https://github.com/wyh-spring-ecosystem-student/spring-boot-student/tree/releasespost
spring-boot-student-spring 工程測試
爲監控而生的多級緩存框架 layering-cache這是我開源的一個多級緩存框架的實現,若是有興趣能夠看一下下