Bean的完整生命週期經歷了各類方法調用,這些方法能夠劃分爲如下幾類:spring
生命週期緩存
建立 ----> 初始化 ---> 銷燬app
1. 實例化對象ide
2. setter注入,執行Bean的屬性依賴注入函數
3. BeanNameAware的setBeanName(), 若是實現該接口,則執行其setBeanName 方法post
4.BeanFactoryAware的setBeanFactory(), 若是實現該接口,則執行其setBeanFactory方法測試
5. BeanPostProcessor的processBeforeInitialization(),若是有關聯的processor,則在Bean初始化以前都會執行這個實例的processBeforeInitialization() 方法spa
綜上:3d
// 後置處理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 執行自定義init方法以前處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( "3.[BeanPostProcessor] ---> postProcessBeforeInitialization 執行init方法[以前]處理") ; return bean; } /** * 執行自定義init方法以後處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println( "5.[BeanPostProcessor] ---> postProcessAfterInitialization 執行init方法[以後]處理") ; return bean; } }
6. InitializingBean的afterPropertiesSet(), 若是實現了該接口,則執行其afterPropertiesSet()方法。Bean定義文件中定義init-method日誌
7.BeanPostProcessors的processAfterInitialization(),若是有關聯的processor,則在Bean初始化以前都會執行這個實例的processAfterInitialization()方法
8.DisposeablebBean的 destory(),在容器關閉時,若是Bean實現了這個接口,則執行他的destory()方法
9. Bean定義文件中定義destroy-method,在容器關閉時,能夠在Bean定義文件中使用「destory-method」定義的方法
注:
1. 單例默認時在容器被加載時候會初始化
2. 多例在每次獲取Bean的對象時候纔會去初始化
bean 初始化 指的就是對象已經建立裏面全部的set方法都已經執行完畢了。 指定方法執行
@Bean(initMethod , destory) 指定初始化和銷燬方法 同時在bean中建立這兩個方法
init是在構造方法以前仍是以後執行? 無參構造! 對象先建立完成後才進行初始化!因此先執行無參構造函數!
補充到上面的過程:
Bean的建立(執行構造函數) --> 初始化(自定義init方法) --> 銷燬
調用close() 方法銷燬單例對象
注意:IOC容器使用Map結合存儲對象,clear() 清除對象
看源碼:
進入查看:
繼續點擊查看:
看第一個:
持續跟進後就是 集合的 clear 方法了
咱們能夠經過實現某些類 去進行初始化的操做!
開發使用的方式:
方法一: 經過@Bean指定init-method 和 destory-method
方法二: 經過讓Bean實現InitializingBean(定義初始化邏輯), DisposableBean(定義銷燬邏輯)
方法三: 使用JSR250(Java規範,不是Spring的): @PostConstruct: 在Bean建立完成而且賦值完成,來執行初始化方法。 @PreDestory: 在容器銷燬Bean以前通知咱們進行清理工做
方法二:
Bean:
@Component public class LifeBean implements InitializingBean, DisposableBean { //構造函數 public LifeBean() { System.out.println("LifeBean Constructor"); } /** 接口InitializingBean的方法 * //解釋 對象有建立 確定也有給屬相賦值的過程!,對象賦值完畢之後才執行該方法 即: (afterPropertiesSet)中文:set方法都走完了時候執行該方法 * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { //等同於 @Bean(init =" ") //解釋 對象有建立 確定也有給屬相賦值的過程!,對象賦值完畢之後才執行該方法 System.out.println("LifeBean ********> 【InitializingBean.afterPropertiesSet】 "); } /** * 接口DisposableBean 的方法 * @throws Exception */ @Override public void destroy() throws Exception { System.out.println("LifeBean ********>【DisposableBean.destroy】"); } }
配置和掃包
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
啓動測試:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); applicationContext1.close(); // System.out.println(applicationContext1); } }
方法三
註解代替了接口:
Bean:
@Component public class LifeBean { //構造函數 public LifeBean() { System.out.println("LifeBean Constructor"); } @PostConstruct public void afterPropertiesSet() throws Exception { //等同於 @Bean(init =" ") //解釋 對象有建立 確定也有給屬相賦值的過程!,對象賦值完畢之後才執行該方法 System.out.println("LifeBean ********> 【InitializingBean.afterPropertiesSet】 "); } @PreDestroy public void destroy() throws Exception { System.out.println("LifeBean ********>【DisposableBean.destroy】"); } }
效果是同樣的:
幾個重要的Aware接口:
1. ApplicationContextAware
過濾器中,不可使用註解方式獲取Bean對象。 作法: 單獨獲取上下文ApplicationContext
後置處理器,實現對Bean初始化加強功能
@Component public class MyApplicationContext implements ApplicationContextAware { //開發時候常常作成全局的 進行使用 private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { LifeBean lifeBean = applicationContext.getBean("lifeBean", LifeBean.class); System.out.println("result————————————————————"+lifeBean.toString()); } }
運行後:結果是沒問題的
問題: Spring底層中爲何可以實現ApplicationContextAware接口,就可以拿到ApplicationContext。
2. BeanNameAware 與 BeanFactoryAware
Bean
@Component public class LifeBean01 implements BeanNameAware, BeanFactoryAware { public LifeBean01() { System.out.println("LifeBean01 對象實例化完成"); } @Override public void setBeanName(String s) { System.out.println("beanName:"+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("beanFactory:"+ beanFactory); } }
配置類:
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
測試:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); applicationContext1.close(); // System.out.println(applicationContext1); } }
IOC容器初始化到哪裏獨享都是循環遍歷getBean方法。
getSingleton(beanName) 先查詢緩存有沒有,看下以前有沒有建立過
Spring Bean生命週期中的後置處理器: BeanPostProcessor接口
從源碼能夠看到是 能夠在 init以前或者以後進行一系列的操做的
加上上面的那幾個接口一塊兒展現下:
後置處理器,單獨處理到別的bean裏面去, 其餘的bean(Spring 自帶的都會走這個方法了)。
init 以前以後,經過後置處理器對bean的初始化進行加強。 能夠作bean耗時統計,日誌打印等等。
Bean:
@Component public class LifeBean01 implements BeanNameAware, BeanFactoryAware, InitializingBean { public LifeBean01() { System.out.println("1. -----------------》LifeBean01 對象實例化完成"); } @Override public void setBeanName(String s) { System.out.println("2. -----------------》對象beanName:"+s); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("3. -----------------》beanFactory:"+ beanFactory); } @Override public void afterPropertiesSet() throws Exception { System.out.println("5. -----------------》 bean init 方法執行"); } }
後置處理器:
// 後置處理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor{ /** * 執行自定義init方法以前處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( beanName + "==========> 執行init方法[以前]處理"); return bean; } /** * 執行自定義init方法以後處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println(beanName +"==========>執行init方法[以後]處理"); return bean; } }
配置類:
@Configuration @ComponentScan("com.toov5.config.beanTest.entity") public class MyConfig { }
測試:
public class test { public test(){ } public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext("com.toov5.config"); // applicationContext1.close(); // System.out.println(applicationContext1); } }
結果:
生命週期流程圖:
描述:
1.實例化對象 (能夠反射, 能夠new)
2. 給對象屬性賦值
3. 檢查是否有Aware依賴,若是有上述的哪些,就進行執行。
總結: 重點無非就是 Aware 和 後置處理器
從源碼中看 setApplicationContext() 方法是在前置獲取的。 經過postProcessBefore前置,裏面的默認方法獲取到上下文對象。
總結:
後置處理器:
@Component public class LifeBean implements BeanNameAware, BeanFactoryAware , InitializingBean, DisposableBean { @Override public void setBeanName(String s) { System.out.println("1.[BeanNameAware] ---> setBeanName"); } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("2.[BeanFactoryAware] ---> setBeanFactory"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("4.[InitializingBean] ---> afterPropertiesSet"); } @Override public void destroy() throws Exception { System.out.println("6.[DisposableBean] ---> distory" ); } }
Bean:
// 後置處理器 @Component public class MyBeanPostProcessor implements BeanPostProcessor { /** * 執行自定義init方法以前處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println( "3.[BeanPostProcessor] ---> postProcessBeforeInitialization 執行init方法[以前]處理") ; return bean; } /** * 執行自定義init方法以後處理 * @param bean * @param beanName * @return * @throws BeansException */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println( "5.[BeanPostProcessor] ---> postProcessAfterInitialization 執行init方法[以後]處理") ; return bean; } }
配置:
@Configuration @ComponentScan("com.spring.test") public class config { }
測試
public class test { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext1 = new AnnotationConfigApplicationContext(config.class); applicationContext1.close(); } }