spring bean的聲明週期

最近忽然想整理一下spring bean的聲明週期,由於忽然發現工做了這麼久,spring bean的生命週期都忘了,平時不怎麼用html

在傳統的Java應用中,bean的生命週期很簡單,使用Java關鍵字 new 進行Bean 的實例化,而後該Bean 就可以使用了。一旦bean再也不被使用,則由Java自動進行垃圾回收。java

相比之下,瞭解spring bean的生命週期,可讓咱們在項目中更改spring的底層源碼,根據咱們的業務來在spring bean的各個週期實現咱們想要的功能spring

bean 的生命週期
1.Spring啓動,查找並加載須要被Spring管理的bean,進行Bean的實例化服務器

2.Bean實例化後對將Bean的引入和值注入到Bean的屬性中函數

3.若是Bean實現了BeanNameAware接口的話,Spring將Bean的Id傳遞給setBeanName()方法post

4.若是Bean實現了BeanFactoryAware接口的話,Spring將調用setBeanFactory()方法,將BeanFactory容器實例傳入.net

5.若是Bean實現了ApplicationContextAware接口的話,Spring將調用Bean的setApplicationContext()方法,將bean所在應用上下文引用傳入進來。3d

6.若是Bean實現了BeanPostProcessor接口,Spring就將調用他們的postProcessBeforeInitialization()方法。htm

7.若是Bean 實現了InitializingBean接口,Spring將調用他們的afterPropertiesSet()方法。相似的,若是bean使用init-method聲明瞭初始化方法,該方法也會被調用對象

8.若是Bean 實現了BeanPostProcessor接口,Spring就將調用他們的postProcessAfterInitialization()方法。

9.此時,Bean已經準備就緒,能夠被應用程序使用了。他們將一直駐留在應用上下文中,直到應用上下文被銷燬。

10.若是bean實現了DisposableBean接口,Spring將調用它的destory()接口方法,一樣,若是bean使用了destory-method 聲明銷燬方法,該方法也會被調用。

 

上面是Spring 中Bean的核心接口和生命週期。可是翻閱JavaDoc文檔發現除了以上接口外,還有另外的初始化過程涉及的接口。

Bean 完整的生命週期

 

 

BeanNameAware.setBeanName() 在建立此bean的bean工廠中設置bean的名稱,在普通屬性設置以後調用,在InitializinngBean.afterPropertiesSet()方法以前調用

BeanClassLoaderAware.setBeanClassLoader(): 在普通屬性設置以後,InitializingBean.afterPropertiesSet()以前調用

BeanFactoryAware.setBeanFactory() : 回調提供了本身的bean實例工廠,在普通屬性設置以後,在InitializingBean.afterPropertiesSet()或者自定義初始化方法以前調用

EnvironmentAware.setEnvironment(): 設置environment在組件使用時調用

EmbeddedValueResolverAware.setEmbeddedValueResolver(): 設置StringValueResolver 用來解決嵌入式的值域問題

ResourceLoaderAware.setResourceLoader(): 在普通bean對象以後調用,在afterPropertiesSet 或者自定義的init-method 以前調用,在 ApplicationContextAware 以前調用。

ApplicationEventPublisherAware.setApplicationEventPublisher(): 在普通bean屬性以後調用,在初始化調用afterPropertiesSet 或者自定義初始化方法以前調用。在 ApplicationContextAware 以前調用。

MessageSourceAware.setMessageSource(): 在普通bean屬性以後調用,在初始化調用afterPropertiesSet 或者自定義初始化方法以前調用,在 ApplicationContextAware 以前調用。

ApplicationContextAware.setApplicationContext(): 在普通Bean對象生成以後調用,在InitializingBean.afterPropertiesSet以前調用或者用戶自定義初始化方法以前。在ResourceLoaderAware.setResourceLoader,ApplicationEventPublisherAware.setApplicationEventPublisher,MessageSourceAware以後調用。

ServletContextAware.setServletContext(): 運行時設置ServletContext,在普通bean初始化後調用,在InitializingBean.afterPropertiesSet以前調用,在 ApplicationContextAware 以後調用注:是在WebApplicationContext 運行時

BeanPostProcessor.postProcessBeforeInitialization() : 將此BeanPostProcessor 應用於給定的新bean實例 在任何bean初始化回調方法(像是InitializingBean.afterPropertiesSet或者自定義的初始化方法)以前調用。這個bean將要準備填充屬性的值。返回的bean示例可能被普通對象包裝,默認實現返回是一個bean。

BeanPostProcessor.postProcessAfterInitialization() : 將此BeanPostProcessor 應用於給定的新bean實例 在任何bean初始化回調方法(像是InitializingBean.afterPropertiesSet或者自定義的初始化方法)以後調用。這個bean將要準備填充屬性的值。返回的bean示例可能被普通對象包裝

InitializingBean.afterPropertiesSet(): 被BeanFactory在設置全部bean屬性以後調用(而且知足BeanFactory 和 ApplicationContextAware)。

————————————銷燬————————————

在BeanFactory 關閉的時候,Bean的生命週期會調用以下方法:

DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(): 在銷燬以前將此BeanPostProcessor 應用於給定的bean實例。可以調用自定義回調,像是DisposableBean 的銷燬和自定義銷燬方法,這個回調僅僅適用於工廠中的單例bean(包括內部bean)

實現了自定義的destory()方法

 

 

通常我平時用的比較多的是@PostConstruct註解,在spring項目中,在一個bean的初始化過程當中,方法執行前後順序爲

靜態代碼塊>代碼塊>Constructor > @Autowired > @PostConstruct
被@PostConstruct修飾的方法會在服務器加載Servlet的時候運行,而且只會被服務器調用一次,相似於Serclet的inti()方法。被@PostConstruct修飾的方法會在構造函數以後,init()方法以前運行。

@PreConstruct說明
被@PreConstruct修飾的方法會在服務器卸載Servlet的時候運行,而且只會被服務器調用一次,相似於Servlet的destroy()方法。被@PreConstruct修飾的方法會在destroy()方法以後運行,在Servlet被完全卸載以前。

@PostConstruct 修飾的方法只能是無參函數,沒有返回類型,不能拋出異常

咱們能夠在其中作一些本身想要的事情,例如初始化加載一些配置等

 

package com.aibao.pos.microshop.wxdev.controller;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Component;

@Component
public class TestAnnotationPreDestroy {
    
    static {
        System.out.println("靜態代碼塊");
    }
    {
        System.out.println("代碼塊");
    }
    public TestAnnotationPreDestroy(){
        System.out.println("構造函數");
    }
    
    
    @PreDestroy
    public void destory() {
        System.out.println("我被銷燬了、、、、、我是用的@PreDestory的方式、、、、、、");
        System.out.println("我被銷燬了、、、、、我是用的@PreDestory的方式、、、、、、");
    }
    
    @PostConstruct
    public void init() {
        System.out.println("我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、");
        System.out.println("我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、");
    }
    
}

輸出:

靜態代碼塊
代碼塊
構造函數
我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、
我被初始化、、、、、我是用的@@PostConstruct的方式、、、、、、

 

http://www.javashuo.com/article/p-ypixtkvs-bd.html
https://blog.csdn.net/tengdazhang770960436/article/details/92692614

https://blog.csdn.net/qq_40194399/article/details/90720963

相關文章
相關標籤/搜索