1. 程式人生 > >spring 所有bean 載入順序

spring 所有bean 載入順序

問題來源:

有一個bean為A,一個bean為B。想要A在容器例項化的時候的一個屬性name賦值為B的一個方法funB的返回值。

如果只是在A裡單純的寫著:

private B b;
private String name = b.funb();

會報錯說nullpointException,因為這個時候b還沒被set進來,所以為null。

解決辦法為如下程式碼,同時學習下spring中  InitializingBean   ,物件構造方法   ,  init-method   的執行順序。

Java程式碼   收藏程式碼
  1. public class A implements InitializingBean {  
  2.  private B b;  
  3.  private String name; // = b.funb();  
  4.  public void setB(B b) {  
  5.   System.out.println("A.setB initialed");  
  6.   this.b = b;  
  7.  }  
  8.  public A() {  
  9.   System.out.println("A initialed");  
  10.  }  
  11.  public void init() {  
  12.   System.out.println("init");  
  13.   this.name = b.funb();  
  14.  }  
  15.  @Override
      
  16.  public String toString() {  
  17.   return super.toString() + this.name;  
  18.  }  
  19.  public void afterPropertiesSet() throws Exception {  
  20.   //其實放在這裡也可以  
  21.   //this.name = b.funb();  
  22.   System.out.println("afterPropertiesSet");  
  23.  }  
  24. }  
  25. public class B {  
  26.  public String funb() {  
  27.   System.out.println("funb"
    );  
  28.   return "B.funb";  
  29.  }  
  30.  public B() {  
  31.   System.out.println("B initialed");  
  32.  }  
  33. }  

spring配置檔案

<beans default-autowire="byName">
      <bean id="a" class="testspring.A" init-method="init">
      </bean>
      <bean id="b" class="testspring.B">
      </bean>
 </beans>

測試程式碼:

 public static void main(String[] args) {
      ApplicationContext context = new FileSystemXmlApplicationContext(
          "src/testspring/bean.xml");
       A a = (A) context.getBean("a");
      System.out.println(a);

 }

程式輸出為:

A initialed
B initialed
A.setB initialed
afterPropertiesSet
init
funb
[email protected]

從這裡看到A的name屬性在bean載入完成的時候也被成功設定為B的funB方法的返回值了,要點就是用init-method來實現。

載入順序也可以看到為:

先建構函式——>然後是b的set方法注入——>InitializingBean   的afterPropertiesSet方法——>init-method方法

總結為:

以下內容是從書中摘錄來的,但是我發現即使摘錄一遍,對其內容的理解也會更加深入!  
一、Spring裝配Bean的過程   
1. 例項化;  
2. 設定屬性值;  
3. 如果實現了BeanNameAware介面,呼叫setBeanName設定Bean的ID或者Name;  
4. 如果實現BeanFactoryAware介面,呼叫setBeanFactory 設定BeanFactory;  
5. 如果實現ApplicationContextAware,呼叫setApplicationContext設定ApplicationContext  
6. 呼叫BeanPostProcessor的預先初始化方法;  
7. 呼叫InitializingBean的afterPropertiesSet()方法;  
8. 呼叫定製init-method方法;  
9. 呼叫BeanPostProcessor的後初始化方法;  


Spring容器關閉過程   
1. 呼叫DisposableBean的destroy();  
2. 呼叫定製的destroy-method方法;

一,單一Bean

  • 裝載

1. 例項化; 
2. 設定屬性值; 
3. 如果實現了BeanNameAware介面,呼叫setBeanName設定Bean的ID或者Name; 
4. 如果實現BeanFactoryAware介面,呼叫setBeanFactory 設定BeanFactory; 
5. 如果實現ApplicationContextAware,呼叫setApplicationContext設定ApplicationContext 
6. 呼叫BeanPostProcessor的預先初始化方法; 
7. 呼叫InitializingBean的afterPropertiesSet()方法; 
8. 呼叫定製init-method方法; 
9. 呼叫BeanPostProcessor的後初始化方法;

  • spring容器關閉

1. 呼叫DisposableBean的destroy(); 
2. 呼叫定製的destroy-method方法;

二,多個Bean的先後順序

  • 優先載入BeanPostProcessor的實現Bean
  • 按Bean檔案和Bean的定義順序按bean的裝載順序(即使載入多個spring檔案時存在id覆蓋)
  • “設定屬性值”(第2步)時,遇到ref,則在“例項化”(第1步)之後先載入ref的id對應的bean
  • AbstractFactoryBean的子類,在第6步之後,會呼叫createInstance方法,之後會呼叫getObjectType方法
  • BeanFactoryUtils類也會改變Bean的載入順序

相關推薦

spring 所有bean 載入順序

問題來源: 有一個bean為A,一個bean為B。想要A在容器例項化的時候的一個屬性name賦值為B的一個方法funB的返回值。 如果只是在A裡單純的寫著: private B b; private String name = b.funb(); 會報錯說null

spring bean載入順序

1、使用Spring @DependsOn控制bean載入順序 該註解用於聲明當前bean依賴於另外一個bean。所依賴的bean會被容器確保在當前bean例項化之前被例項化。 1.1 用法 直接或者間接標註在帶有@Component註解的類上面。 直接或者間接標註在帶有@B

使用Spring @DependsOn控制bean載入順序

  spring容器載入bean順序是不確定的,spring框架沒有約定特定順序邏輯規範。但spring保證如果A依賴B(如beanA中有@Autowired B的變數),那麼B將先於A被載入。但如果beanA不直接依賴B,我們如何讓B仍先載入呢? 控制bean初始化順序 可能有些

SpringBean載入過程

在載入Bean時需要經歷11個步驟 instantiate bean 物件例項化 屬性注入 如果Bean 實現了BeanNameAware 執行setBeanName 方法 如果Bean實現了BeanFactoryAware 或者ApplicationConte

詳解Spring Boot 配置載入順序及屬性載入順序

先給大家介紹下spring boot 配置載入順序,具體內容如下所示: 使用 Spring Boot 會涉及到各種各樣的配置,如開發、測試、線上就至少 3 套配置資訊了。Spring Boot 可以輕鬆的幫助我們使用相同的程式碼就能使開發、測試、線上環境使用不同的配置。 在 Spring B

Spring Boot 配置載入順序詳解

使用 Spring Boot 會涉及到各種各樣的配置,如開發、測試、線上就至少 3 套配置資訊了。Spring Boot 可以輕鬆的幫助我們使用相同的程式碼就能使開發、測試、線上環境使用不同的配置。 在 Spring Boot 裡面,可以使用以下幾種方式來載入配置。本章

Springbean建立順序

解答以下疑惑:Spring配置檔案裡bean,究竟是按什麼樣的順序載入呢?Spring專案在部署時,究竟建立了多少各beanFactory呢?按什麼順序建立?長話短說,總結成如下幾點:Rule1:首先讀取WEB-INF/web.xml檔案,該檔案內一般會配置spring-co

spring boot實戰(第十篇)Spring boot Bean載入原始碼分析

public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostPro

Springbean載入兩次的原因

有時候我們發現定時器呼叫了兩次,這個可能跟Spring載入bean有關,最好的驗證方法是,寫構造方法,看看Spring載入的時候初始化了幾次。 導致這個原因一般是在web.xml中配置的。這樣配置會導致bean載入兩次,所以bean會多次載入。

Springbean載入的過程

我們直接看AbstractApplicationContext.java中的方法,bean載入的過程如圖,主要有下面的幾個步驟 其實這裡可以簡化成 1、讀取配置檔案,獲取所有的bean定義(單例,class,構造器,成員變數) 2、提供可以修改beanfactory

SpringMVC事務失效的一種情況-bean載入順序問題

首先給大家看一個範例java代理的範例: public class MyInvocationHandler implements InvocationHandler { // 目標物件,也就是我們主要的業務,主要目的要做什麼事 private Object deleg

死磕spring,大致還原springbean載入過程

總的來說: 對傳入的name做轉化,去除&開頭獲得真實beanname,通過aliasMap獲取是否有別名 檢查是否有bean的完整的引用快取;如果沒有,看singletonsCurrentlyInCreation,是不是這個bean正在建立中,看ea

SpringBoot系列教程之Bean載入順序之錯誤使用姿勢闢謠

在網上查詢 Bean 的載入順序時,看到了大量的文章中使用@Order註解的方式來控制 bean 的載入順序,不知道寫這些的博文的同學自己有沒有實際的驗證過,本文希望通過指出這些錯誤的使用姿勢,讓觀文的小夥伴可以知道@Order的具體的應用場景 原文地址: SpringBoot系列教程之Bean載入順序

Spring Bean載入順序

一,單一Bean 裝載 1. 例項化; 2. 設定屬性值; 3. 如果實現了BeanNameAware介面,呼叫setBeanName設定Bean的ID或者Name; 4. 如果實現BeanFactoryAware介面,呼叫setBeanFactory 設定Bean

Spring創建Bean順序

XML col 通過 分享 -o 信息 pattern 依賴關系 str 一直對Spring創建bean的順序很好奇,現在總算有時間寫個代碼測試一下。不想看過程的小夥伴可以直接看結論 目錄結構: 其中:bean4、bean5包下的class沒有註解@Component,測

Spring Boot 學習系列(09)—自定義Bean順序加載

rri 學習 內容安全 master sys const nco 單純 分享圖片 此文已由作者易國強授權網易雲社區發布。歡迎訪問網易雲社區,了解更多網易技術產品運營經驗。Bean 的順序加載有些場景中,我們希望編寫的Bean能夠按照指定的順序進行加載。比如,有UserSer

指定springbean啟動的順序

參考連結: https://www.jb51.net/article/125846.htm 使用DependsOn Spring 中的 DependsOn 註解可以保證被依賴的bean先於當前bean被容器建立, 但是如果不理解Spring中bean載入過程會對 DependsOn 有誤解,自

spring原始碼-BeanPostProcessor-3.3 spring原始碼-bean載入-2

  一、BeanPostProcessor這個是spring容器的拓展之一,是用於獲取bean的時候處理對應的物件;   二、常用場景,在獲取bean的時候,重新初始化bean的屬性等。   三、實現方式(加入容器後,呼叫其他bean的時候,通過BeanPostProcessor來進行處理) im

spring原始碼-Aware-3.4 spring原始碼-bean載入-2

  一、Aware介面,這個也是spring的拓展之一,為啥要單獨拿出來講呢,因為他相比於BeanFactoryPostProcessor,BeanPostProcessor的實用性更加高,並且在具體的業務中也可以靈活使用,主要是能夠達到解耦的目的。   二、常用的Aware介面有:第一類:BeanName

Spring學習--懶載入(延遲初始化Bean)與自動裝配

**延遲初始化Bean:** 也叫惰性初始化,指的是不提前初始化Bean,而是隻有在真正使用的時候才建立以 及初始化Bean。 配置方式很簡單,只需要在<bean>標籤上指定"lazy-init"屬性值為true即可延遲初始 化Bean。 Sp