日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Spring IoC 詳解(四)

 印度阿三17 2019-12-11

IoC:Inverse of Control(控制反轉(zhuǎn))

為了更好的理解用可以這樣通俗易懂的這樣講:IOC主要是說(shuō)是new一個(gè)類(lèi)來(lái)使用,方式分為:開(kāi)發(fā)這手動(dòng)創(chuàng)建和SpringIOC容器創(chuàng)建(控制反轉(zhuǎn))。

  • 讀作“反轉(zhuǎn)控制”,更好理解,不是什么技術(shù),而是一種設(shè)計(jì)思想,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán),交由Spring框架來(lái)管理。

  • 正控:若要使用某個(gè)對(duì)象,需要自己去負(fù)責(zé)對(duì)象的創(chuàng)建

  • 反控:若要使用某個(gè)對(duì)象,只需要從 Spring 容器中獲取需要使用的對(duì)象,不關(guān)心對(duì)象的創(chuàng)建過(guò)程,也就是把創(chuàng)建對(duì)象的控制權(quán)反轉(zhuǎn)給了Spring框架

  • 好萊塢法則:Don’t call me ,I’ll call you

一個(gè)例子

控制反轉(zhuǎn)顯然是一個(gè)抽象的概念,我們舉一個(gè)鮮明的例子來(lái)說(shuō)明。

在現(xiàn)實(shí)生活中,人們要用到一樣?xùn)|西的時(shí)候,第一反應(yīng)就是去找到這件東西,比如想喝新鮮橙汁,在沒(méi)有飲品店的日子里,最直觀的做法就是:買(mǎi)果汁機(jī)、買(mǎi)橙子,然后準(zhǔn)備開(kāi)水。值得注意的是:這些都是你自己“主動(dòng)”創(chuàng)造的過(guò)程,也就是說(shuō)一杯橙汁需要你自己創(chuàng)造。

然而到了今時(shí)今日,由于飲品店的盛行,當(dāng)我們想喝橙汁時(shí),第一想法就轉(zhuǎn)換成了找到飲品店的聯(lián)系方式,通過(guò)電話等渠道描述你的需要、地址、聯(lián)系方式等,下訂單等待,過(guò)一會(huì)兒就會(huì)有人送來(lái)橙汁了。

請(qǐng)注意你并沒(méi)有“主動(dòng)”去創(chuàng)造橙汁,橙汁是由飲品店創(chuàng)造的,而不是你,然而也完全達(dá)到了你的要求,甚至比你創(chuàng)造的要好上那么一些。

Spring IoC 闡述

這就是一種控制反轉(zhuǎn)的理念,上述的例子已經(jīng)很好的說(shuō)明了問(wèn)題,我們?cè)賮?lái)描述一下控制反轉(zhuǎn)的概念:控制反轉(zhuǎn)是一種通過(guò)描述(在 Java 中可以是 XML 或者注解)并通過(guò)第三方(Spring)去產(chǎn)生或獲取特定對(duì)象的方式。

  • 好處:
    降低對(duì)象之間的耦合
    我們不需要理解一個(gè)類(lèi)的具體實(shí)現(xiàn),只需要知道它有什么用就好了(直接向 IoC 容器拿)

主動(dòng)創(chuàng)建的模式中,責(zé)任歸于開(kāi)發(fā)者,而在被動(dòng)的模式下,責(zé)任歸于 IoC 容器,基于這樣的被動(dòng)形式,我們就說(shuō)對(duì)象被控制反轉(zhuǎn)了。(也可以說(shuō)是反轉(zhuǎn)了控制)


Spring IoC 容器

Spring 會(huì)提供 IoC 容器來(lái)管理和容納我們所開(kāi)發(fā)的各種各樣的 Bean,并且我們可以從中獲取各種發(fā)布在 Spring IoC 容器里的 Bean,并且通過(guò)描述可以得到它。

Spring IoC 容器的設(shè)計(jì)

Spring IoC 容器的設(shè)計(jì)主要是基于以下兩個(gè)接口:

  • BeanFactory

  • ApplicationContext

其中 ApplicationContext 是 BeanFactory 的子接口之一,換句話說(shuō):BeanFactory 是 Spring IoC 容器所定義的最底層接口,而 ApplicationContext 是其最高級(jí)接口之一,并對(duì) BeanFactory 功能做了許多的擴(kuò)展,所以在絕大部分的工作場(chǎng)景下,都會(huì)使用 ApplicationContext 作為 Spring IoC 容器。

ApplicationContext 繼承關(guān)系

BeanFactory

從上圖中我們可以幾乎看到, BeanFactory 位于設(shè)計(jì)的最底層,它提供了 Spring IoC 最底層的設(shè)計(jì),為此,我們先來(lái)看看該類(lèi)中提供了哪些方法:

由于這個(gè)接口的重要性,所以有必要在這里作一下簡(jiǎn)短的說(shuō)明:

  • 【getBean】 對(duì)應(yīng)了多個(gè)方法來(lái)獲取配置給 Spring IoC 容器的 Bean。
    ① 按照類(lèi)型拿 bean:
    bean = (Bean) factory.getBean(Bean.class);
    注意:要求在 Spring 中只配置了一個(gè)這種類(lèi)型的實(shí)例,否則報(bào)錯(cuò)。(如果有多個(gè)那 Spring 就懵了,不知道該獲取哪一個(gè))
    ② 按照 bean 的名字拿 bean:
    bean = (Bean) factory.getBean("beanName");
    注意:這種方法不太安全,IDE 不會(huì)檢查其安全性(關(guān)聯(lián)性)
    ③ 按照名字和類(lèi)型拿 bean:(推薦)
    bean = (Bean) factory.getBean("beanName", Bean.class);

  • 【isSingleton】 用于判斷是否單例,如果判斷為真,其意思是該 Bean 在容器中是作為一個(gè)唯一單例存在的。而【isPrototype】則相反,如果判斷為真,意思是當(dāng)你從容器中獲取 Bean,容器就為你生成一個(gè)新的實(shí)例。
    注意:在默認(rèn)情況下,【isSingleton】為 ture,而【isPrototype】為 false

  • 關(guān)于 type 的匹配,這是一個(gè)按 Java 類(lèi)型匹配的方式

  • 【getAliases】方法是獲取別名的方法

這就是 Spring IoC 最底層的設(shè)計(jì),所有關(guān)于 Spring IoC 的容器將會(huì)遵守它所定義的方法。

ApplicationContext

根據(jù) ApplicationContext 的類(lèi)繼承關(guān)系圖,可以看到 ApplicationContext 接口擴(kuò)展了許許多多的接口,因此它的功能十分強(qiáng)大,所以在實(shí)際應(yīng)用中常常會(huì)使用到的是 ApplicationContext 接口,因?yàn)?BeanFactory 的方法和功能較少,而 ApplicationContext 的方法和功能較多。

通過(guò)上一篇 IoC 的例子,我們來(lái)認(rèn)識(shí)一個(gè) ApplicationContext 的子類(lèi)——ClassPathXmlApplicationContext。

  1. 先在【src】目錄下創(chuàng)建一個(gè) 【bean.xml】 文件:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www./schema/beans"
       xmlns:xsi="http://www./2001/XMLSchema-instance"
       xsi:schemaLocation="http://www./schema/beans http://www./schema/beans/spring-beans.xsd">
    <!-- 通過(guò) xml 方式裝配 bean -->
    <bean name="source" class="pojo.Source">
        <property name="fruit" value="橙子"/>
        <property name="sugar" value="多糖"/>
        <property name="size" value="超大杯"/>
    </bean>
</beans>
  1. 這里定義了一個(gè) bean ,這樣 Spring IoC 容器在初始化的時(shí)候就能找到它們,然后使用 ClassPathXmlApplicationContext 容器就可以將其初始化:

ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
Source source = (Source) context.getBean("source", Source.class);

System.out.println(source.getFruit());
System.out.println(source.getSugar());
System.out.println(source.getSize());

這樣就會(huì)使用 Application 的實(shí)現(xiàn)類(lèi) ClassPathXmlApplicationContext 去初始化 Spring IoC 容器,然后開(kāi)發(fā)者就可以通過(guò) IoC 容器來(lái)獲取資源了啦!

關(guān)于 Spring Bean 的裝配以及一些細(xì)節(jié),會(huì)在下一篇文章中講到

ApplicationContext 常見(jiàn)實(shí)現(xiàn)類(lèi):

1.ClassPathXmlApplicationContext:
讀取classpath中的資源

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

2:FileSystemXmlApplicationContext:-
讀取指定路徑的資源

ApplicationContext ac = new FileSystemXmlApplicationContext("c:/applicationContext.xml");

3.XmlWebApplicationContext:
需要在Web的環(huán)境下才可以運(yùn)行

XmlWebApplicationContext ac = new XmlWebApplicationContext(); // 這時(shí)并沒(méi)有初始化容器
ac.setServletContext(servletContext); // 需要指定ServletContext對(duì)象
ac.setConfigLocation("/WEB-INF/applicationContext.xml"); // 指定配置文件路徑,開(kāi)頭的斜線表示W(wǎng)eb應(yīng)用的根目錄
ac.refresh(); // 初始化容器

BeanFactory 和 ApplicationContext 的區(qū)別:

  • BeanFactory:是Spring中最底層的接口,只提供了最簡(jiǎn)單的IoC功能,負(fù)責(zé)配置,創(chuàng)建和管理bean。
    在應(yīng)用中,一般不使用 BeanFactory,而推薦使用ApplicationContext(應(yīng)用上下文),原因如下。

  • ApplicationContext:
    1.繼承了 BeanFactory,擁有了基本的 IoC 功能;
    2.除此之外,ApplicationContext 還提供了以下功能:
    ① 支持國(guó)際化;
    ② 支持消息機(jī)制;
    ③ 支持統(tǒng)一的資源加載;
    ④ 支持AOP功能;


Spring IoC 的容器的初始化和依賴(lài)注入

雖然 Spring IoC 容器的生成十分的復(fù)雜,但是大體了解一下 Spring IoC 初始化的過(guò)程還是必要的。這對(duì)于理解 Spring 的一系列行為是很有幫助的。

注意:Bean 的定義和初始化在 Spring IoC 容器是兩大步驟,它是先定義,然后初始化和依賴(lài)注入的。

  • Bean 的定義分為 3 步:
    1.Resource 定位
    Spring IoC 容器先根據(jù)開(kāi)發(fā)者的配置,進(jìn)行資源的定位,在 Spring 的開(kāi)發(fā)中,通過(guò) XML 或者注解都是十分常見(jiàn)的方式,定位的內(nèi)容是由開(kāi)發(fā)者提供的。
    2.BeanDefinition 的載入
    這個(gè)時(shí)候只是將 Resource 定位到的信息,保存到 Bean 定義(BeanDefinition)中,此時(shí)并不會(huì)創(chuàng)建 Bean 的實(shí)例
    3.BeanDefinition 的注冊(cè)
    這個(gè)過(guò)程就是將 BeanDefinition 的信息發(fā)布到 Spring IoC 容器中
    注意:此時(shí)仍然沒(méi)有對(duì)應(yīng)的 Bean 的實(shí)例。

做完了以上 3 步,Bean 就在 Spring IoC 容器中被定義了,而沒(méi)有被初始化,更沒(méi)有完成依賴(lài)注入,也就是沒(méi)有注入其配置的資源給 Bean,那么它還不能完全使用。

對(duì)于初始化和依賴(lài)注入,Spring Bean 還有一個(gè)配置選項(xiàng)——【lazy-init】,其含義就是是否初始化 Spring Bean。在沒(méi)有任何配置的情況下,它的默認(rèn)值為 default,實(shí)際值為 false,也就是 Spring IoC 默認(rèn)會(huì)自動(dòng)初始化 Bean。如果將其設(shè)置為 true,那么只有當(dāng)我們使用 Spring IoC 容器的 getBean 方法獲取它時(shí),它才會(huì)進(jìn)行 Bean 的初始化,完成依賴(lài)注入。

來(lái)源:https://www./content-4-595351.html

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

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多