Spring IoC學習

IoC是什麼
java

IoC-Inversion of Control,即"控制反轉",不是什麼技術,而是一種設計思想。Java開發中,IoC意味着將設計好的對象交給IoC容器控制,再也不是傳統的在對象內部直接控制。
web

  • 誰控制誰,控制什麼spring

    傳統Java SE程序中,直接在對象內部經過new建立對象,由程序主動去建立依賴對象;數組

    IoC機制有專門的一個容器來建立這些對象,由IoC容器來控制對象的建立;session

    誰控制誰?IoC容器控制對象;app

    控制什麼?主要控制了外部資源的獲取(不僅是對象包括好比文件等)框架

  • 爲什麼是反轉,哪些方面反轉了函數

    傳統的應用程序,在對象中主動控制去直接獲取依賴對象,也就是正轉;工具

    反轉則是由IoC容器幫忙建立及注入依賴對象;測試

    爲什麼是反轉?由容器進行查找及注入依賴對象,對象只是被動的接受依賴對象,因此是反轉;

    哪些方面反轉了?依賴對象的獲取被反轉了


IoC能作什麼

    傳統的應用程序在類內部主動建立依賴對象,從而致使類與類之間高耦合,難於測試;

    IoC容器,把建立和查找依賴對象的控制權交給了容器,由容器進行注入,組合對象,因此對象與對象間是鬆耦合;

    IoC很好的體現了面向對象設計法則之一 ——好萊塢法則:別找咱們,咱們找你;即由IoC容器幫對象找相應的依賴對象並注入,而不是由對象主動去找


IoC 和 DI

DI - Dependency Injection,依賴注入:組件之間的依賴關係由容器在運行期間決定,形象的說,由容器動態的將某個依賴關係注入到組件中。

經過依賴注入機制,只需簡單的配置,就可指定目標須要的資源,完成自身的業務邏輯,而不須要關心具體的資源來自何處。

關鍵點:

  • 誰依賴於誰:固然是應用程序依賴IoC容器

  • 爲何須要依賴:應用程序須要IoC容器提供對象須要的外部資源

  • 誰注入誰:IoC容器注入應用程序某個對象,應用程序依賴的對象

  • 注入了什麼:注入某個對象所需的外部資源(包括對象、資源、常量數據)


IoC 和 DI關係,實際上是同一律唸的不一樣角度描述,因爲控制反轉概念比較含糊,2004年又給出新的名字:依賴注入,相對IoC而言,」依賴注入「明確描述了」被注入對象依賴IoC容器配置依賴對象


Spring IoC容器的依賴,有兩層含義:Bean依賴IoC容器容器注入Bean的依賴資源

Bean依賴容器,指的是容器負責建立並管理Bean,是Bean和IoC容器間的依賴關係

容器注入Bean的依賴資源,依賴資源能夠是Bean、外部文件、常量數據等,由容器負責組裝Bean之間的依賴關係,此處的依賴爲Bean之間的依賴關係,可認爲是傳統的類與類關聯、聚合、組合關係


Spring IoC容器實現依賴資源注入的方式

構造器注入:容器在實例化Bean時注入所需依賴資源,經過配置文件定義Bean中指定構造函數參數進行注入

setter注入:經過構造器、靜態工廠或實例工廠實例好Bean後,經過調用Bean類的setter方法進行注入依賴

方法注入:經過配置方式替換掉Bean方法,也就是經過配置改變Bean方法功能


Spring IoC容器注入配置簡寫

1、構造器注入

    1)常量值

        簡寫:<constructor-arg index="0" vlaue="xxx" />

        全寫:<constructor-arg index="0"><value>xxx</value></constructor-arg>

    2)引用

        簡寫:<constructor-arg index="0" ref="bean name" />

        全寫:<constructor-arg index="0"><ref bean="bean name" /></constructor-arg>

2、setter注入

    1) 常量

        簡寫:<property index="0" value="xxx" />

        全寫:<property index="0"><value>xxx</value></property>

    2) 引用

        簡寫:<property index="0" ref="bean name" />

        全寫:<property index="0"><ref bean="bean name" /></property>

    3) 數組(array)

        <property name="array name">

            <array value-type="java.lang.String">

                <value>xxx</value>

                xxx

            </array>

        </property>

    4) 列表(List)

    <property name="list name">

        <list value-type="java.lang.String">

            <value>xxx</value>

            ...

        </list>

    </property>

    5) 集合(set)

        <property name="set name">

            <set>

                <value>xxx</value>

                ...

            </set>

        </property>

    5) 字典(map)

        <property name="map name">

            <map key-type="java.lang.String" value-type="java.lang.String">

                <entry key="xxx" value="xxx" />

                ...

            </map>

        </property>

    6) Properties


3、使用P命名空間簡化setter注入

    <beans xmlns:p="http://www.springframework.org/schema/p"> //指定P命名空間

        <bean id="bean" class="com.spring.constroller.XXX" p:id="value" />

        //常量setter注入方式,等價於<property name="id" value="value" />


        <bean id="bean2" class="com.spring.controller.XXX" p:id-ref="xxx" />

        //引用setter注入方式,其等價於<property name="id" ref="xxx" />

    </beans>


BeanFactory和ApplicationContext

Spring經過xml配置文件描述Bean和Bean直接的依賴關係,利用Java語言的反射機制實例化Bean並創建Bean之間的依賴關係。

BeanFactory(org.springframework.beans.factory.BeanFactory)是Spring框架最核心的接口,提供了高級IoC的配置機制。

ApplicationContext(應用上下文,org.springframework.context.ApplicationContext)創建在BeanFactory基礎上,提供了面向應用的gongneng,提供了國際化支持和框架事件體系。

通常地,稱BeanFactory爲IoC容器,而稱ApplicationContext爲應用上下文

從用途上進行劃分,BeanFactory是Spring框架的基礎設施,面向SpringApplicationContext面向Spring框架的使用者


初始化BeanFactory

使用Spring配置文件提供配置信息,經過BeanFactory裝載配置文件,啓動Spring IoC容器。

經過BeanFactory啓動IoC容器時,並不會初始化配置文件中的Bean,初始化動做發生在第一個調用時。

注意初始化BeanFactory時,必須提供一種日誌框架,好比Log4j,在類路徑下提供Log4j配置文件,這樣啓動Spring容器纔不會報錯


ApplicationContext介紹

如若BeanFactory是Spring的心臟,那ApplicationContext就是Spring完整的身軀。ApplicationContext由BeanFactory派生而來,提供了面向實際應用的功能。

ApplicationContext體系結構

其主要實現類是ClassPathXMLApplicationContextFileSystemXMLApplicationContext,前者默認從類路徑加載配置文件,後者從文件系統中裝載配置文件。


ApplicationContext初始化

和BeanFactory初始化類似,ApplicationContext初始化也很簡單,若是配置文件放在類路徑下,優先使用ClassPathXMLApplicationContext實現類:

ApplicationContext context = new ClassPathXMLApplicationContext("com/bbtao/context/beans.xml");

等同於: "classpath:com/bbtao/context/beans.xml"

若是配置文件放在文件系統路徑下,優先考慮FileSystemXMLApplicationContext實現類:

ApplicationContext context = new FileSystemXMLApplicationContext("com/bbtao/context/beans.xml");

等同於: "file:com/bbtao/context/beans.xml"


ApplicationContext與BeanFactory的重大區別

BeanFactory在初始化IoC容器時,並未實例化Bean,直到第一次訪問調用某個Bean時才進行實例化操做;

ApplicationContext,在初始化應用上下文時就實例化全部單實例的Bean


AnnotationConfigApplicationContext

Spring 3.0支持基於類註解的配置方式,主要功能源自Spring的JavaConfig子項目。一個標註@Configuration註解的POJO便可提供Spring所需的Bean配置信息

Spring爲基於註解類的配置提供了專門的ApplicationContext實現類:AnnotationConfigApplicationContext


WebApplicationContext

WebApplicationContext,專爲Web應用準備的,容許從相對於Web根目錄的路徑中裝載配置文件完成初始化工做

整個WebApplicationContext對象做爲屬性放到ServletContext中,以便Web應用環境能夠訪問到Spring應用上下文。爲此,Spring提供一個工具類WebApplicationContextUtils,經過該類的getWebApplicationContext(ServletContext sc),就可從ServletContext中獲取WebApplicationContext實例。


Spring 2.0在WebApplicationContext中爲Bean添加了三個新的做用域:request做用域、session做用域和global session做用域。

WebApplicationContext中定義了一個常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,上下文啓動時,WebApplicationContext實例以此放置在ServletContext的屬性列表中。所以,經過如下語句從Web容器中獲取WebApplicationContext:

    WebApplicationContext context = (WebApplicationContext)servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);

WebApplicationContext初始化

初始化方式,和BeanFactory、ApplicationContext有所不一樣,由於WebApplicationContext初始化時須要ApplicationContext實例,也就是說WebApplicationContext必須在擁有Web容器的前提下才能完成啓動工做。

Spring提供了用於啓動WebApplicationContext的Servlet和Web容器監聽器

  • org.springframework.web.context.ContextLoaderServlet

  • org.springframework.web.context.ContextLoaderListener

二者內部都實現了啓動WebApplicationContext實例的邏輯,根據Web容器的狀況,在web.xml文件中進行配置就能夠了

示例(ContextLoaderListener)

<!-- 指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value>

</context-param>

<!-- 聲明Web容器監聽器 -->

<listener>

    <listener-class>org.springframe.web.context.ContextLoaderListener</listener-class>

</listener>

ContextLoaderListener經過Web容器上下文參數contextConfigLocation獲取Spring配置文件的位置。用戶也能夠指定多個配置文件,用逗號空格冒號分割都可。


不支持容器監聽器的低版本Web容器中,採用ContextLoaderServlet完成啓動工做:

示例(ContextLoaderServlet):

<!--  指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContext.xml</param-value>

</context-param>

<!-- 聲明自動啓動的Servlet -->

<servlet>

    <servlet-name>contextLoaderServlet</servlet-name>

    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

    <!--  啓動順序 -->

    <load-on-startup>1</load-on-startup>

</servlet>


因爲WebApplicationContext須要使用日誌功能,將Log4j的配置文件放到類路徑(/WEB-INF/classess/)下,Log4j引擎可順利啓動。若是Log4j配置文件放在其餘位置,那必須在web.xml中指定配置文件位置

Spring爲Log4j引擎提供了兩個實現類:Log4jConfigServlet,和Log4jConfigListener;無論採用哪一種方式,必須保證Log4j配置信息先於Spring配置文件加載

示例:

 <!-- 指定Spring配置文件 -->

<context-param>

    <param-name>contextConfigLocation</param-name>

    <param-value>classpath:applicationContex.xml</param-value>

</context-param>

<!-- 指定Log4j配置文件 -->

<context-param>

    <param-name>log4jConfigLocation</param-name>

    <param-value>/WEB-INF/log4j.properties</param-value>

</context-param>

<!--  配置Log4j的自啓動Servlet -->

<servlet>

    <servlet-name>log4jConfigServlet<servlet-name>

    <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>

    <!-- 指定Log4jConfigServlet的啓動順序,必定要先於WebApplicationContext啓動 -->

    <load-on-startup>1</load-on-startup>

</serlvet>

<!-- 聲明WebApplicationContext的自啓動Servlet-->

<servlet>

    <servlet-name>contextLoaderServlet</servlet-name>

    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>

    <load-on-startup>2</load-on-startup>

</servlet>

若是使用Web監聽器,則必須將Log4jConfigListener放在ContextLoaderListener前面,這樣才保證Log4j的啓動先於WebApplicationContext完成。

相關文章
相關標籤/搜索