1. 程式人生 > >Spring是什麼、spring容器、IOC和DI

Spring是什麼、spring容器、IOC和DI

1.Spring

(1)Spring是什麼?

是一個輕量級的、用來簡化企業級應用開發的開發框架。

注:
    a.簡化開發:
    Spring對常用的api做了簡化,比如,使用Spring
    jdbc來訪問資料庫,就不用再考慮如何獲取連線、關閉連線、處理異常等等。
    b.解耦:
    Spring容器(Spring框架的一個模組)幫我們管理
    物件(包括物件的建立及物件之間的依賴關係),
    這樣一來,物件之間的耦合度會大大降低,提供高了
    系統的維護性。
    c.整合其它框架:
    Spring可以將其它一些常用的框架整合進來,比如
    可以將Quartz,MyBatis等整合進來。

(2)Spring容器

1)Spring容器是什麼?

Spring框架的一個核心模組,用於管理物件。

注:
    管理物件指的是,spring容器會用我們建立物件,
並且建立物件之間的依賴關係。

2)如何啟動Spring容器?

step1.導包。

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>3.2.8.RELEASE</version>
</dependency>

step2.新增配置檔案(applicationContext.xml)。

將配置檔案新增到main/resources下。

step3.啟動Spring容器。

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

3)建立物件

a.方式一  使用無參構造器

step1. 給類新增無參構造器(預設構造器)。
step2.  在配置檔案當中,使用bean元素來進行配置。

<!-- 
    使用無參構造器來建立物件。
    id屬性要求唯一。
    class屬性指定類名(要寫完整的類名)。
    注:
        在spring框架當中,將Spring容器所管理
        的物件稱之為一個bean。   
    -->
    <bean id="ap1" class="first.Apple"/>

step3. 啟動容器,呼叫容器提供的getBean方法。

    //通過容器獲得物件
    Apple ap1 = 
        ac.getBean("ap1",Apple.class);

b.方式二  使用靜態工廠方法 (瞭解)

<!-- 
    使用靜態工廠方法來建立物件。
    factory-method屬性用於指定一個靜態
    方法(static修飾的方法)。
    注:
      容器會呼叫指定類的靜態方法來建立
    物件。
 -->
<bean id="cal1" 
class="java.util.Calendar" 
factory-method="getInstance"/>

c.方式三  使用例項工廠方法 (瞭解)

<!-- 
    使用例項工廠方法來建立物件。
    factory-bean屬性指定bean的id,
    factory-method屬性指定一個方法。
    注:
        容器會呼叫該bean的方法來建立一個
        物件。
 -->
 <bean id="date2" factory-bean="cal1" 
 factory-method="getTime"/>

4)作用域

a.預設情況下,對於某個bean,容器只會建立一個例項。

b.如果要讓容器建立多個例項,需要設定bean的作用域。

<!-- 
        scope屬性用於指定作用域,
        預設值是singleton,如果將值設定
        為prototype,則容器會建立多個例項。
     -->
    <bean id="eb1" 
        class="basic.ExampleBean" 
        scope="prototype"/> 

5)生命週期

spring容器在建立好物件之後,會呼叫初始化方法, 在銷燬該物件之前,會呼叫銷燬方法。

    <!-- 
        init-method屬性:  指定初始化方法
        destroy-method屬性:指定銷燬方法。
        注:
            銷燬方法只有當作用域為singleton
            才有效。
     -->    
    <bean id="mb1" 
    class="basic.MessageBean" 
    init-method="init" 
    destroy-method="destroy" 
    scope="singleton"/> 

6)延遲載入

a.預設情況下,容器啟動之後,會將所有作用域為singleton的bean例項化。

b.延遲載入指的是,通過設定lazy-init="true"告訴容器, 啟動之後不再建立其例項。

    <!-- 
        lazy-init屬性如果值為true,表示
        延遲載入。
     -->
    <bean id="lb1" class="basic.LazyBean" 
    lazy-init="true"/>

(3)IOC和DI

1)IOC是什麼? (Inversion Of Controll 控制反轉)

物件之間的依賴關係應該由容器來建立。

2)DI是什麼? (Dependency Injection 依賴注入)

容器通過呼叫set方法或者構造器來建立物件之間的依賴關係。

注:
    IOC是目標,DI是手段。

3)set方法注入

step1. 為類新增set方法。

step2. 在配置檔案當中,使用property元素來配置set 方法注入。

    <!-- 
        property元素表示採用set方法注入。
        name屬性用於指定set方法名
        (容器會將b大寫,前面新增set來
        構造方法名)。
        ref屬性用於指定被注入的bean的id。
     -->
    <bean id="a1" class="ioc.A">
        <property name="b" ref="b1"/>
    </bean>

step3. 啟動容器,呼叫getBean方法。

3)set方法注入

4)構造器注入

step1. 新增相應的帶參的構造器。

step2. 使用<constructor-arg>元素來配置構造器注入。

 <bean id="cpu" class="ioc.Cpu"/>
    <!-- 
        constructor-arg元素用來配置構造器
        注入。
        index屬性用於指定引數的下標。
        ref屬性用於指定被注入的bean的id。
     -->
    <bean id="cp" class="ioc.Computer">
        <constructor-arg index="0" 
        ref="cpu"/>
    </bean>

step3. 啟動容器,呼叫getBean方法。

4)自動裝配 (瞭解)

a.什麼是自動裝配?

容器依據某些規則,自動查詢符合要求的物件,
然後建立物件之間的依賴關係。
注: 容器仍然要呼叫set方法或者構造器。

b.如何自動裝配?

使用autowire屬性指定裝配的規則:
<bean id="wt1" class="autowire.Waiter"/>
    <!-- 
        autowire屬性表示讓容器自動建立
        物件之間的依賴關係,有三個值:
        byName:
            以屬性名作為bean的id,查詢
            對應的bean,然後呼叫set方法。
            注:如果找不到對應的bean,
            不會呼叫set方法。
        byType:
            以屬性型別作為bean的型別,查詢
            對應的bean,然後呼叫set方法。
            注:
                如果找不到對應的bean,
                不會呼叫set方法。
                如果找到多個bean,會出錯。
        constructor:
            類似於byType,只不過是呼叫構造器來
            完成  注入。  
     -->
<bean id="rest" 
    class="autowire.Restaurant" 
    autowire="byType"/> 

5)注入基本型別的值

<bean id="vb" class="value.ValueBean">
    <property name="name" value="小包總"/>
    <property name="age" value="20"/>
</bean>

6)注入集合型別的值

a.支援四種集合型別的值的注入,分別是List,Set,Properties,Map。

b.注入方式如下:

    <property name="interest">
            <list>
                <value>打獵</value>
                <value>看書</value>
                <value>程式設計</value>
                <value>程式設計</value>
            </list>
        </property>
    <property name="city">
        <set>
            <value>洛陽</value>
            <value>金陵</value>
            <value>開封</value>
        </set>
    </property>
    <property name="score">
        <map>
            <entry key="english" 
                value="59.5"/>
            <entry key="math" 
                value="17"/>    
        </map>
    </property>
    <property name="db">
        <props>
            <prop key="username">tom</prop>
            <prop key="pwd">1234</prop>
        </props>
    </property>

7)引用的方式注入集合型別的值

    <!-- 
        將集合型別的值配置成一個bean
     -->
    <util:list id="interestBean">
        <value>打獵</value>
        <value>看書</value>
        <value>程式設計</value>
    </util:list>
    <util:set id="cityBean">
        <value>北京</value>
        <value>南京</value>
        <value>東京</value>
    </util:set>
    <util:map id="scoreBean">
        <entry key="english" value="80"/>
        <entry key="math" value="90"/>
    </util:map> 
    <util:properties id="dbBean">
        <prop key="username">John</prop>
        <prop key="pwd">1234</prop>
    </util:properties>
    <bean id="vb2" class="value.ValueBean">
        <property name="interest" 
        ref="interestBean"/>
        <property name="city"
        ref="cityBean"/>
        <property name="score"
        ref="scoreBean"/>
        <property name="db"
        ref="dbBean"/>
    </bean>

8)讀取properties檔案的內容

    <!-- 
        讀取properties檔案的內容。
        location屬性用於指定要讀取的檔案的位置。
        注:
            classpath:表示依據類路徑去查詢相應的
            檔案。
     -->
     <util:properties id="config" 
     location="classpath:config.properties"/>

9)spring表示式

a.spring表示式的作用?

可以用來讀取其它bean的屬性

b.用法如下圖: