SpringIOC原理

SpringIOC原理

1.概念

Spring通過一個配置文件描述Bean及Bean之間的依賴關系,利用Java語言的反射功能實例化Bean并建立Bean之間的依賴關系。Spring的IOC容器在完成這些底層工作的基礎上,還提供了Bean實例緩存、生命周期管理、Bean實例代理、事件發布、資源裝載等高級服務。

2.Spring容器高層視圖

Spring啟動時讀取應用程序提供的Bean配置信息,并在Spring容器中生成一份相應的Bean配置注冊表,然后根據這張注冊表實例化Bean,裝配好Bean之間的依賴關系,為上層應用提供準備就緒的運行環境。其中Bean緩存池為HashMap實現。

在這里插入圖片描述

3.IOC容器實現

BeanFactory-框架基礎設施

BeanFactory是Spring框架的基礎設施,面向Spring本身;ApplicationContext面向使用Spring框架的開發者,幾乎所有的應用場合我們都直接使用ApplicationContext而非底層的BeanFactory。

在這里插入圖片描述

  1. BeanDefinitionRegistry注冊表

    Spring配置文件中每一個節點元素在Spring容器里都通過一個BeanDefinition對象表示,它描述了Bean的配置信息。而BeanDefinitionRegistry接口提供了向容器手工注冊BeanDefinition對象的方法。

  2. BeanFactory頂層接口

    位于類結構樹的頂端,它最主要的方法就是getBean(String beanName),該方法從容器中返回特定名稱的Bean,BeanFactory的功能通過其他的接口得到不斷擴展。

  3. ListableBeanFactory

    該接口定義了訪問容器中Bean基本信息的若干方法,如查看Bean的個數、獲取某一類型Bean的配置名、查看容器中是否包括某一Bean等方法。

  4. HierarchicalBeanFactory父子級聯

    HierarchicalBeanFactory接口,Spring的IOC容器可以建立父子層級關聯的容器體系,子容器可以訪問父容器中的Bean,但父容器不能訪問子容器的Bean。Spring使用父子容器實現了很多功能,比如在SpringMVC中,展現層Bean位于一個子容器,而業務層和持久層的Bean位于父容器中。這樣,展現層Bean就可以引用業務層和持久層的Bean,而業務層和持久層的Bean則看不到展現層的Bean。

  5. ConfigurableBeanFactory

    是一個重要的接口,增強了IOC的可定制性,它定義了設置類裝載器、屬性編輯器、容器初始化后置處理器等方法。

  6. AutoWireCapableBeanFactory自動裝配

    定義了將容器中的Bean按某種規則(如按名字匹配、按類型匹配等)進行自動裝配的方法。

  7. SingletonBeanRegistry運行期間注冊單例Bean

    定義了運行在運行期間向容器注冊單實例Bean的方法;對于單實例(singleton)的Bean來說,BeanFactory會緩存Bean實例,所以第二次使用getBean()獲取Bean時將直接從IOC容器的緩存中獲取Bean實例。Spring在DefaultSingletonBeanRegistry類中提供了一個用于緩存單實例Bean的緩存器,它是一個用HashMap實現的緩存器,單實例的Bean以beaName為鍵保存在這個HashMap中。

  8. 依賴日志框架

    在初始化BeanFactory時,必須為其提供一種日志框架,比如使用Log4J,即在類路徑下提供Log4J的配置文件,這樣啟動Spring容器才不會報錯。

ApplicationContext面向開發應用

ApplicationContext由BeanFactory派生而來,提供了更多面向實際應用的功能。ApplicationContext繼承了HierarchiBeanFactory和ListableBeanFactory接口,在此基礎上,還通過多個其他的接口擴展了BeanFactory的功能:

在這里插入圖片描述

  1. ClassPathXmlApplicationContetx:默認從類路徑加載配置文件
  2. FileSystemXmlApplicationContext:默認從文件系統中裝載配置文件
  3. ApplicationEventPublisher:讓容器擁有發布應用上下文事件的功能,包括容器啟動事件、關閉事件等。
  4. MessageSource:為應用提供i18n國際化消息訪問的功能。
  5. ResourcePatternResolver:所有ApplicationContext實現類都實現了類似于PathMatchingResourcePatternResolver的功能,可以通過帶前綴的Ant風格的資源文件路徑裝載Spring的配置文件。
  6. LifeCycle:該接口是Spring2.0加入的,該接口提供了start()和stop()兩個方法,主要用于控制異步處理過程。在具體使用時,該接口同時被ApplicationContext實現及具體Bean實現,ApplicationContext會將start/stop的信息傳遞給容器中所有實現了該接口的Bean,以達到管理和控制JMX、任務調度等目的。
  7. ConfigurableApplicationContext擴展于ApplicationContext,它新增加了兩個主要的方法:refresh()和close(),讓ApplicationContext具有啟動、刷新和關閉應用上下文的能力。在應用上下文關閉的情況下調用refresh()即可啟動應用上下文,在已經啟動的狀態下,調用refresh()則清除緩存并重新裝載配置信息,而調用close()則可關閉應用的上下文。

WebApplication體系結構

WebApplicationContext是專門為Web應用準備的,它允許從相對于Web根目錄的路徑中裝載配置文件完成初始化工作。從WebApplicationContext中可以獲得ServletContext的引用,整個Web應用上下文對象將作為屬性放置到ServletContext中,以便Web應用環境可以訪問Spring應用上下文。

在這里插入圖片描述

4.Spring Bean作用域

Spring3中為Bean定義了5種作用域分別為singleton(單例)、prototype(原型)、request、session和global session,5種作用域說明如下:

singleton:單例模式(多線程下不安全)

singleton:單例模式,SpringIOC容器只會存在一個共享的Bean實例,無論有多少個Bean引用它,始終指向同一對象。該模式在多線程下是不安全的。Singleton作用域是Spring中的缺省作用域,也可以顯示的將Bean定義為Singleton模式,配置為:

<bean id = “userDao” class = "com.ioc.USerDaoImpl scope = “singleton”>

prototype:原型模式每次使用時創建

prototype:原型模式,每次通過Spring容器獲取prototype定義的bean時,容器都將創建一個新的Bean實例,每個Bean實例都有自己的屬性和狀態,而對無狀態的bean使用singleton作用域。

Request:一次request一個實例

request:在一次Http請求中,容器會返回該Bean的同一實例。而對不同的Http請求則會產生新的Bean,而且該bean僅在當前HttpRequest內有效,當前Http請求結束,該bean實例也將會被銷毀。

<bean id = “loginAction” class = “com.cnblogs.Login” scope=“request”>

session

session:在一次HttpSession中,容器會返回該Bean的同一實例。而對不同的Session請求則會創建新的實例,該Bean實例僅在當前Session內有效。同Http請求相同,每一次session請求創建新的實例,而不同的實例之間不共享屬性,且實例僅在自己的session請求內有效,請求結束,則實例將被銷毀。

<bean id = “userPreference” class = “com.ioc.UserPreference” scope=“session”>

global Session

global Session:在一個全局的HttpSession中,容器會返回該Bean的同一個實例,僅在使用portlet context時有效。

5.Spring Bean生命周期

實例化

實例化一個Bean,也就是我們常說的new。

IOC依賴注入

按照Spring上下文對實例化的Bean進行配置,也就是依賴注入。

setBeanName實現

如果整個Bean已經實現了BeanNameAware接口,會調用它實現的setBeanName(String)方法,此處傳遞的就是Spring配置文件中Bean的id值。

BeanFactoryAware實現

如果整個Bean已經實現了BeanFactoryAware接口,會調用它實現的setBeanFactory,setBeanFactory(BeanFactory)傳遞的時Spring工廠自身(可以用這個方式來獲取其他Bean,只需在Spring配置文件中配置一個普通的Bean就可以)。

ApplicationContextAware實現

如果這個Bean已經實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文(同樣這個方式也可以實現步驟4的內容,但比4更好,因為ApplicationContext就是BeanFactory的子接口,有更多的實現方法)。

postProcessBeforeInitialization接口實現-初始化預處理

如果這個Bean關聯PostProcessor接口,將會調用postProcessBeforeInitialization(Object obj,String s),BeanPostProcessor經常被用作是Bean內容的更改,并且由于這個是Bean初始化結束時調用那個的方法,也可以被應用于內存或緩存技術。

init-method

如果Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法

postProcessAfterInitialization

如果這個Bean關聯了BeanPostProcessor接口,將會調用postProcessAfterInitialization(Object obj,String s)方法。

注:以上工作完成以后就可以應用這個Bean可,那這個Bean是一個Singleton的,所以一般情況下我們調用同一個id的Bean會是在內容地址相同的實例,當然在Spring配置文件中可以配置非Singleton。

Destory過期自動清理階段

當Bean不再需要時,會經過清理階段,如果Bean實現了DisposableBean這個接口,會調用那個其實現的destroy()方法。

destroy-method自動配置清理

最后,如果這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷毀方法。

在這里插入圖片描述

bean標簽有兩個重要的屬性(init-method和destroy-method).用它們你可以自己定制初始化和注銷方法。它們也有相應的注解(@PostConstruct和@PreDestroy)。

<bean id =“” class = “” init-method=“初始化方法” destroy-method=“銷毀方法”>

6.依賴注入的四種方式

構造器注入

/*帶參數 ,方便利用構造器進行注入*/
public CatDaoImpl(String message){this.message = message;
}
<bean id = "CatDaoImpl" class = "com.CatDaoImpl"><constructor-arg value="message"></constructor-arg>
</bean>

setter方法注入

public class Id{private int id;public int getId(){return id;}public void setId(int id){this.id = id;}  
}
<bean id = "id" class = "com.id"><property name = "id" value="123"></property>
</bean>

靜態工廠注入

靜態工廠顧名思義,就是通過調用靜態工廠的方法來獲取自己需要的對象,為了讓Spring管理所有對象,我們不能直接通過"工程類.靜態方法()來獲取對象,而是依然通過Spring注入的形式獲取":

public class DaoFactory{//靜態工廠public static final FactoryDao getStaticFactoryDaoImpl(){return new StaticFacotryDaoImpl();}
}public class SpringAction{private FactoryDao staticFactoryDao;//注入對象//注入對象的set方法public void setStaticFactoryDao(FactoryDao staticFactoryDao){this.staticFactoryDao = staticFactoryDao;}
}
// factory-method = "getStaticFactoryDaoImpl"指定調用哪個工廠方法
<bean name = "springAction" class = "SpringAction"><!--使用靜態工廠的方法注入對象,對應下面的配置文件--><property name="staticFactoryDao" ref="staticFactoryDao"></property>
</bean> <!--此處獲取對象的方式是從工廠類中獲取靜態方法-->
<bean name="staticFactoryDao" class="DaoFactory" factory-method="getStatictoryDaoImpl">
</bean>

實例工廠

實例工廠的意思是獲取對象實例的方法不是靜態的,所以你需要首先new工廠類,再調用普通的實例方法:

public class DaoFactory{//實例工廠public FactoryDao getFactoryDaoImpl(){return new FactoryDaoImpl();}
}
public class SpringAction{private FactoryDao factoryDao;//注入對象public void setFactoryDao(FactoryDao factoryDao) {this.factoryDao = factoryDao;}
}
<bean name = "springAction" class ="SpringAction"><!--使用實例工廠的方法注入對象,對應下面的配置文件--><property name = "factoryDao" ref="factoryDao"></property>
</bean>
<!--此處獲取對象的方式是從工廠類中獲取實例方法-->
<bean name = "daoFactory" class = "com.DaoFactory"></bean>
<bean name = "factoryDao" factory-bean="daoFactory" factory-method = "getFactoryDaoImpl">
</bean>

5.種不同方式的自動裝配

Spring裝配包括手動裝配和自動裝配,手動裝配是由基于xml裝配、構造方法、setter方法等

自定裝配由五種自動裝配的方式,可以用來指導Spring容器用自動裝配方式來進行依賴注入。

5.1no

no:默認的方式是不進行自動裝配,通過顯示設置ref屬性來進行裝配。

5.2byName

byName:通過參數名自動裝配,Spring容器在配置文件種發現bean的autowire屬性被設置成byName,之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。

5.3byType

byType:通過參數類型自動裝配,Spring容器在配置文件種發現bean的autowire屬性被設置成byType,之后容器試圖匹配、裝配和該bean屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。

5.4constructor

constructor:這個方式類似于byType,但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。

5.5autodetect

之后容器試圖匹配、裝配和該bean的屬性具有相同名字的bean。

5.3byType

byType:通過參數類型自動裝配,Spring容器在配置文件種發現bean的autowire屬性被設置成byType,之后容器試圖匹配、裝配和該bean屬性具有相同類型的bean。如果有多個bean符合條件,則拋出錯誤。

5.4constructor

constructor:這個方式類似于byType,但是要提供給構造器參數,如果沒有確定的帶參數的構造器參數類型,將會拋出異常。

5.5autodetect

autodetect:首先嘗試使用constructor來自動裝配,如果無法工作,則使用byType方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/42927.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42927.shtml
英文地址,請注明出處:http://en.pswp.cn/web/42927.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

AI提示詞:AI輔導「數學作業」

輔導孩子作業對許多家長來說可能是一件頭疼的事&#xff0c;但這部分工作可以在一定程度上交給AI來完成。 打開ChatGPT4,輸入以下內容&#xff1a; # Role 數學輔導專家## Profile - author: 姜小塵 - version: 02 - LLM: Kimi - language: 中文 - description: 專門為小學生…

加密算法詳解:對稱加密、非對稱加密、Hash算法

對稱加密、非對稱加密和哈希算法是信息安全中的三種主要加密技術&#xff0c;它們各自有不同的特點和用途&#xff1a; 對稱加密&#xff08;Symmetric Encryption&#xff09; 工作原理&#xff1a;使用相同的密鑰進行加密和解密。速度&#xff1a;通常非常快&#xff0c;適…

Elasticsearch:Node.js ECS 日志記錄 - Morgan

這是之前系列文章&#xff1a; Elasticsearch&#xff1a;Node.js ECS 日志記錄 - Pino Elasticsearch&#xff1a;Node.js ECS 日志記錄 - Winston 中的第三篇文章。在今天的文章中&#xff0c;我將描述如何使用 Morgan 包針對 Node.js 應用進行日子記錄。此 Morgan Node.j…

包裝器 std::function

使用前&#xff0c;包頭文件&#xff1a;#include <functional> std::function 是 C標準庫 中的一個通用函數包裝器&#xff1b; 它可以儲存、復制、調用任何可調用的對象&#xff0c;包括&#xff1a;函數指針、成員函數、綁定的成員函數、lambda表達式、仿函數等。 1…

Selenium Grid- 讓自動化分布式執行變得可能

什么是 Selenium Grid&#xff1f; Selenium Grid 是 Selenium 的三大組件之一&#xff0c;允許用戶同時在不同的機器和系統上測試不同瀏覽器。 也就是說 Selenium Grid 支持分布式的測試執行。它可以讓你的測試用例在一個分布式的執行環境中運行。 由上圖可見&#xff0c;測試…

linux:基礎知識及命令[圖表]

lsof:查找文件 普通文件、目錄、進程&#xff08;/proc&#xff09;、輸入輸出設備&#xff08;/dev&#xff09;、網絡字節流socket、鏈接文件、管道文件 基本用法 lsof&#xff1a;列出所有打開的文件。lsof /path/to/file&#xff1a;列出打開指定文件的所有進程。lsof -…

大話光學原理:4.散射:瑞利、拉曼、米氏和布里淵

這是一縷柔和的光&#xff0c;在空氣的舞臺上輕盈地跳躍。它悠然自得&#xff0c;在寧靜的空間中緩緩前行。然而&#xff0c;一片細薄透明的介質擋住了它的腳步&#xff0c;它毫無預兆地撞上了這片障礙。在這短暫的接觸中&#xff0c;它被分解成無數微小的粒子&#xff0c;被迫…

增強現實(AR)與虛擬現實(VR)的區別?

隨著科技的飛速發展&#xff0c;增強現實&#xff08;AR&#xff09;與虛擬現實&#xff08;VR&#xff09;技術在各個領域展現出巨大的潛力和應用前景。這兩種技術雖然在體驗和實現方式上有所不同&#xff0c;但都為用戶提供了全新的感知體驗。本文將詳細解析AR和VR的概念、區…

機器視覺/自然語言/生成式人工智能綜合應用實驗平臺-實訓平臺-教學平臺

AIGC是人工智能1.0時代進入2.0時代的重要標志&#xff0c;MIT 科技評論也將Al合成數據列為2022年十大突破性技術之一&#xff0c;甚至將生成性Al(Generative Al) 稱為是AI領域過去十年最具前景的進展。同時&#xff0c;AIGC領域崗位需求數量暴漲。高校方面在人工智能專業與機器…

javascript 處理###分隔的字符串

在 JavaScript 中&#xff0c;可以使用 split 方法將字符串按 ### 分隔成數組。以下是一個示例代碼&#xff0c;展示了如何處理由 ### 分隔的字符串&#xff1a; 示例代碼 // 示例字符串 let str "part1###part2###part3###part4";// 使用 split 方法按 ### 分隔字…

DEJA_VU3D - Cesium功能集 之 122-體元渲染(官方Voxels)

前言 編寫這個專欄主要目的是對工作之中基于Cesium實現過的功能進行整合,有自己琢磨實現的,也有參考其他大神后整理實現的,初步算了算現在有差不多實現小140個左右的功能,后續也會不斷的追加,工作原因可能無法像以前那樣周更2-3篇,但是閑下來還是會不定期的更新,Cesium…

tensorflow張量生成以及常用函數

張量tensor&#xff1a;多維數組&#xff08;列表&#xff09; 階&#xff1a;張量的維數 維數 階 名字 例子 0-D 0 標量 scalar s 1&#xff0c; 2&#xff0c; 3 1-D 1 向量 vector…

How do I format markdown chatgpt response in tkinter frame python?

題意&#xff1a;怎樣在Tkinter框架中使用Python來格式化Markdown格式的ChatGPT響應&#xff1f; 問題背景&#xff1a; Chatgpt sometimes responds in markdown language. Sometimes the respond contains ** ** which means the text in between should be bold and ### te…

Python數據分析-天氣類型預測分析

一、研究背景 近年來&#xff0c;隨著全球氣候變化的加劇&#xff0c;天氣預報和氣象預測變得越來越重要。準確的天氣預測不僅能夠幫助人們做好日常生活的安排&#xff0c;還能在農業生產、防災減災等方面起到關鍵作用。隨著大數據技術和機器學習算法的快速發展&#xff0c;利…

科普文:深入理解負載均衡(四層負載均衡、七層負載均衡)

概敘 網絡模型&#xff1a;OSI七層模型、TCP/IP四層模型、現實的五層模型 應用層&#xff1a;對軟件提供接口以使程序能使用網絡服務&#xff0c;如事務處理程序、文件傳送協議和網絡管理等。&#xff08;HTTP、Telnet、FTP、SMTP&#xff09; 表示層&#xff1a;程序和網絡之…

基于vue的地圖特效(飛線和標注)

這段代碼的主要功能是在頁面加載完成后&#xff0c;初始化一個 echarts 地圖圖表&#xff0c;并配置了相關的地理數據、散點數據、線條數據以及樣式效果&#xff0c;最后在指定的 div 元素中進行展示。 需要再vue中的框架實現&#xff0c;不能單獨直接運行。 標注 type: effe…

Python30 使用Gensim庫實現Word2Vec對文本進行處理

1.Word2Vec Word2Vec 是一種將詞語表示為向量的技術&#xff0c;能夠捕捉詞語之間的語義關系。它由 Google 的 Tomas Mikolov 等人在 2013 年提出&#xff0c;廣泛應用于自然語言處理任務中。其核心概念主要包括&#xff1a; 詞嵌入&#xff08;Word Embeddings&#xff09; …

使用昇騰芯片進行多卡訓推時使用hccl_tools.py為npu分配ip報錯問題解決辦法

目錄 問題描述問題產生原因解決辦法最終執行并驗證參考網站命令擴展 問題描述 昇騰芯片&#xff08;910b/310p等&#xff09;進行多卡訓練或者推理時需要先獲取并配置每張npu的ip信息&#xff0c;因此需要執行類似下面問題&#xff1a; python mindformers/tools/hccl_tools.…

[AI 大模型] Meta LLaMA-2

文章目錄 [AI 大模型] Meta LLaMA-2簡介模型架構發展新技術和優勢示例 [AI 大模型] Meta LLaMA-2 簡介 Meta LLaMA-2 是 Meta 推出的第二代開源大型語言模型&#xff08;LLM&#xff09;&#xff0c;旨在為研究和商業應用提供強大的自然語言處理能力。 LLaMA-2 系列模型包括從…

Python實現串口通信(Python+Stm32)詳解

Python實現串口通信&#xff08;PythonStm32&#xff09;詳解 引言 在現代的嵌入式系統開發和自動化控制中&#xff0c;串口通信是一種非常常見的通信方式。Python作為一種易于學習且功能強大的編程語言&#xff0c;結合Stm32微控制器&#xff0c;能夠實現高效、靈活的串口通…