一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

Spring01——你應(yīng)該了解的,有關(guān) IOC 容器的一切

 路人甲Java 2020-06-13

從本文開始,將開始介紹關(guān)于 Spring 的一些常見知識點(diǎn)。關(guān)注我的公眾號「Java面典」,每天 10:24 和你一起了解更多 Java 相關(guān)知識點(diǎn)。

在如今的 Java Web 開發(fā)中,Spring 生態(tài)圈占據(jù)著巨大的市場份額。幾乎是每個(gè)互聯(lián)網(wǎng)公司都在用 Spring 生態(tài)圈的東西。所以掌握Spring 相關(guān)知識就成為了我們工作和面試中必不可少的技能。今天將為各位帶來 Spring IOC 的相關(guān)知識。

概念

IOC —— Inversion of Control,即“控制反轉(zhuǎn)”,不是什么技術(shù),而是一種設(shè)計(jì)思想。指的是將設(shè)計(jì)好的對象交給容器控制,而不是傳統(tǒng)的在對象內(nèi)部直接控制。

Spring 的 IOC 實(shí)現(xiàn)離不了DI(DI——Dependency Injection,即“依賴注入”。依賴注入指的是由容器動(dòng)態(tài)的將某個(gè)依賴關(guān)系注入到組件之中)。

Spring 通過一個(gè)配置文件描述 Bean 及 Bean 之間的依賴關(guān)系,利用 Java 語言的反射功能實(shí)例化 Bean 并建立 Bean 之間的依賴關(guān)系。

IOC容器實(shí)現(xiàn)

IOC容器UML.png

IOC 容器主要由 BeanFactory 和 ApplicationContext 組成。BeanFactory 是 Spring 框架的基礎(chǔ)設(shè)施,面向 Spring 本身;ApplicationContext 面向使用 Spring 框架的開發(fā)者,幾乎所有的應(yīng)用場合我們都直接使用 ApplicationContext 而非底層的 BeanFactory。

BeanFactory

BeanFactory 是 Spring 框架的基礎(chǔ)設(shè)施,面向 Spring 本身,BeanFactory 主要有以下組件:

  • BeanDefinitionRegistry:注冊表,提供了向容器手工注冊 BeanDefinition 對象的方法。Spring 配置文件中每一個(gè)節(jié)點(diǎn)元素在 Spring 容器里都通過一個(gè) BeanDefinition 對象表示,它描述了 Bean 的配置信息;

  • BeanFactory:頂層接口。它最主要的方法就是 getBean(String beanName),該方法從容器中返回特定名稱的 Bean;

  • ListableBeanFactory:該接口定義了訪問容器中 Bean 基本信息的若干方法,如查看 Bean 的個(gè)數(shù)、獲取某一類型 Bean 的配置名、查看容器中是否包括某一 Bean 等方法;

  • HierarchicalBeanFactory:父子級聯(lián) IOC 容器的接口,子容器可以通過接口方法訪問父容器; 通過HierarchicalBeanFactory 接口, Spring 的 IOC 容器可以建立父子層級關(guān)聯(lián)的容器體系,子容器可以訪問父容器中的 Bean,但父容器不能訪問子容器的 Bean。Spring 使用父子容器實(shí)現(xiàn)了很多功能,比如在 Spring MVC 中,展現(xiàn)層 Bean 位于一個(gè)子容器中,而業(yè)務(wù)層和持久層的 Bean 位于父容器中。這樣,展現(xiàn)層 Bean 就可以引用業(yè)務(wù)層和持久層的 Bean,而業(yè)務(wù)層和持久層的 Bean 則看不到展現(xiàn)層的 Bean;

  • ConfigurableBeanFactory:定義了設(shè)置類裝載器、屬性編輯器、容器初始化后置處理器等方法,增強(qiáng)了 IOC 容器的可定制性;

  • AutowireCapableBeanFactory:定義了將容器中的 Bean 按某種規(guī)則(如按名字匹配、按類型匹配等)進(jìn)行自動(dòng)裝配的方法;

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

  • 依賴日志框架:在初始化 BeanFactory 時(shí),必須為其提供一種日志框架,比如使用 Log4J, 即在類路徑下提供 Log4J 配置文件,這樣啟動(dòng) Spring 容器才不會報(bào)錯(cuò)。

ApplicationContext 面向開發(fā)應(yīng)用

ApplicationContext 由 BeanFactory 派 生 而 來 , 提 供 了 更 多 面 向 實(shí) 際 應(yīng) 用 的 功 能 。ApplicationContext 繼承了 HierarchicalBeanFactory 和 ListableBeanFactory 接口,在此基礎(chǔ)上,還通過多個(gè)其他的接口擴(kuò)展了 BeanFactory 的功能:

  • ClassPathXmlApplicationContext:默認(rèn)從類路徑加載配置文件;
  • FileSystemXmlApplicationContext:默認(rèn)從文件系統(tǒng)中裝載配置文件;
  • ApplicationEventPublisher:讓容器擁有發(fā)布應(yīng)用上下文事件的功能,包括容器啟動(dòng)事件、關(guān)閉事件等;
  • MessageSource:為應(yīng)用提供 i18n 國際化消息訪問的功能;
  • ResourcePatternResolver: 所 有 ApplicationContext 實(shí)現(xiàn)類都實(shí)現(xiàn)了類似于 PathMatchingResourcePatternResolver 的功能,可以通過帶前綴的 Ant 風(fēng)格的資源文件路徑裝載 Spring 的配置文件;
  • LifeCycle:該接口是 Spring 2.0 加入的,該接口提供了 start()和 stop()兩個(gè)方法,主要用于控制異步處理過程。在具體使用時(shí),該接口同時(shí)被 ApplicationContext 實(shí)現(xiàn)及具體Bean 實(shí)現(xiàn), ApplicationContext 會將 start/stop 的信息傳遞給容器中所有實(shí)現(xiàn)了該接口的 Bean,以達(dá)到管理和控制 JMX、任務(wù)調(diào)度等目的;
  • ConfigurableApplicationContext:擴(kuò)展于 ApplicationContext,它新增加了兩個(gè)主要的方法: refresh()和 close(),讓 ApplicationContext 具有啟動(dòng)、刷新和關(guān)閉應(yīng)用上下文的能力。在應(yīng)用上下文關(guān)閉的情況下調(diào)用 refresh()即可啟動(dòng)應(yīng)用上下文,在已經(jīng)啟動(dòng)的狀態(tài)下,調(diào)用 refresh()則清除緩存并重新裝載配置信息,而調(diào)用 close()則可關(guān)閉應(yīng)用上下文。

WebApplicationContext

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

四種依賴注入方式

構(gòu)造器注入

/*帶參數(shù),方便利用構(gòu)造器進(jìn)行注入*/
public CatDaoImpl(String message){ 
    this. message = message; 
} 

<bean id="CatDaoImpl" class="com.CatDaoImpl"> 
    <constructor-arg value=" message "></constructor-arg> 
</bean>

setter 方法注入

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>

靜態(tài)工廠注入

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

public class DaoFactory { 
    //靜態(tài)工廠 
    public static final FactoryDao getStaticFactoryDaoImpl(){ 
        return new StaticFacotryDaoImpl(); 
    } 
} 

public class SpringAction { 

    //注入對象
    private FactoryDao staticFactoryDao; 
    //注入對象的 set 方法 
    public void setStaticFactoryDao(FactoryDao staticFactoryDao) { 
        this.staticFactoryDao = staticFactoryDao; 
    } 
} 

<bean name="springAction" class=" SpringAction" > 
    <!--使用靜態(tài)工廠的方法注入對象,對應(yīng)下面的配置文件--> 
    <property name="staticFactoryDao" ref="staticFactoryDao"></property> 
 </bean> 
 
<!--此處獲取對象的方式是從工廠類中獲取靜態(tài)方法--> 
<bean name="staticFactoryDao" class="DaoFactory" factory-method="getStaticFactoryDaoImpl"></bean>

實(shí)例工廠

實(shí)例工廠的意思是獲取對象實(shí)例的方法不是靜態(tài)的,所以你需要首先 new 工廠類,再調(diào)用普通的實(shí)例方法:

public class DaoFactory { 
    //實(shí)例工廠 
    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"> 
    <!--使用實(shí)例工廠的方法注入對象,對應(yīng)下面的配置文件--> 
    <property name="factoryDao" ref="factoryDao"></property> 
</bean> 

 <!--此處獲取對象的方式是從工廠類中獲取實(shí)例方法--> 
<bean name="daoFactory" class="com.DaoFactory"></bean> 
<bean name="factoryDao" factory-bean="daoFactory" factory-method="getFactoryDaoImpl"></bean>

五種不同方式的自動(dòng)裝配

Spring 裝配包括手動(dòng)裝配和自動(dòng)裝配,手動(dòng)裝配是有基于 xml 裝配、構(gòu)造方法、setter 方法等;自動(dòng)裝配有五種方式,可以用來指導(dǎo) Spring 容器用自動(dòng)裝配方式來進(jìn)行依賴注入:

  1. no:默認(rèn)的方式是不進(jìn)行自動(dòng)裝配,通過顯式設(shè)置 ref 屬性來進(jìn)行裝配;
  2. byName:通過參數(shù)名 自動(dòng)裝配,Spring 容器在配置文件中發(fā)現(xiàn) bean 的 autowire 屬性被設(shè)置成 byname,之后容器試圖匹配、裝配和該 bean 的屬性具有相同名字的 bean;
  3. byType:通過參數(shù)類型自動(dòng)裝配,Spring 容器在配置文件中發(fā)現(xiàn) bean 的 autowire 屬性被設(shè)置成 byType,之后容器試圖匹配、裝配和該 bean 的屬性具有相同類型的 bean; 注意:使用 byType 首先需要保證同一類型的對象,在 Spring 容器中唯一,若不唯一會報(bào)不唯一的異常。
  4. constructor:這個(gè)方式類似于 byType, 但是要提供給構(gòu)造器參數(shù),如果沒有確定的帶參數(shù)的構(gòu)造器參數(shù)類型,將會拋出異常;
  5. autodetect:首先嘗試使用 constructor 來自動(dòng)裝配,如果無法工作,則使用 byType 方式。

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    日韩精品一级片免费看| 国产欧美日韩精品自拍| 国产又长又粗又爽免费视频| 黄色片一区二区三区高清| 欧美老太太性生活大片| 色播五月激情五月婷婷| 日韩偷拍精品一区二区三区| 国产欧美另类激情久久久| 大香蕉精品视频一区二区| 色婷婷国产精品视频一区二区保健| 十八禁日本一区二区三区| 亚洲a级一区二区不卡| 在线精品首页中文字幕亚洲| 大伊香蕉一区二区三区| 午夜国产成人福利视频| 亚洲中文字幕一区三区| 五月婷婷六月丁香亚洲| 沐浴偷拍一区二区视频| 亚洲国产精品久久网午夜| 欧美午夜视频免费观看| 国产精品蜜桃久久一区二区| 日系韩系还是欧美久久| 欧美午夜一级艳片免费看| 亚洲精品一区三区三区| 热情的邻居在线中文字幕| 免费高清欧美一区二区视频| 欧美国产日产综合精品| 午夜福利国产精品不卡| 日本欧美一区二区三区就| 国产精品第一香蕉视频| 久热人妻中文字幕一区二区| 懂色一区二区三区四区| 久久碰国产一区二区三区| 丰满少妇被猛烈撞击在线视频| 五月天丁香婷婷狠狠爱| 国产欧美性成人精品午夜| 日韩夫妻午夜性生活视频| 欧美字幕一区二区三区| 亚洲免费视频中文字幕在线观看| 中文字幕人妻av不卡| 国产在线视频好看不卡|