淺談spring依賴注入


了解依賴注入

前言

先了解下控制反轉--轉自知乎的國哥

如果一個類A 的功能實現需要借助於類B,那么就稱類B是類A的依賴,如果在類A的內部去實例化類B,那么兩者之間會出現較高的耦合,一旦類B出現了問題,類A也需要進行改造,如果這樣的情況較多,每個類之間都有很多依賴,那么就會出現牽一發而動全身的情況,程序會極難維護,並且很容易出現問題。要解決這個問題,就要把A類對B類的控制權抽離出來,交給一個第三方去做,把控制權反轉給第三方,就稱作控制反轉(IOC Inversion Of Control)控制反轉是一種思想,是能夠解決問題的一種可能的結果,而依賴注入(Dependency Injection)就是其最典型的實現方法。由第三方(我們稱作IOC容器)來控制依賴,把他通過構造函數、屬性或者工廠模式等方法,注入到類A內,這樣就極大程度的對類A和類B進行了解耦

想理解控制反轉,就得想清楚這個第三方,在spring中便是IOC容器。將原本兩個耦合性很強的對象分給中介第三方進行控制。

依賴注入是實現控制反轉的一種方式,依賴注入是將實例變量傳入到一個對象中去的過程、方式、一種設計模式。依賴注入方式下,注入將依賴傳給調用方,不是像原來的調用方直接使用依賴。所以很明顯也是為了解耦,參考下wiki的圖,了解大概分類

image-20200526220650913

可以參考下官網的介紹

image-20200526211204989

上面的官網中講到依賴注入是依靠這兩個主要的方式依賴-基於構造器的依賴注入和基於setter的依賴注入。下面就講下詳細的實現方式。

實現依賴注入

1、構造器注入

在上一篇的spring入門篇提了,特別是三種方式,這里再記錄一下

環境

先總體的項目小測配置以及定義的各個類

image-20200526152135081

實體類

package com.yhy.pojo;

public class Hello {
    private String str;

    public Hello(String str) {
        this.str = str;
    }

    /**
     * @return String return the str
     */
    public String getStr() {
        return str;
    }

    /**
     * @param str the str to set
     */
    public void setStr(String str) {
        this.str = str;
    }

    public void show() {
        System.out.println(str);
    }

}

測試類

 @Test
    public void test()
    {
        //獲得spring的上下文內容
        //拿到容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //使用容器獲得對象
        Hello hello = (Hello) context.getBean("hello");
       
        hello.show();
    }

使用有參構造有幾個方法

beans.xml中使用三種方式

  • 使用參數名
 <bean id="hello" class="com.yhy.pojo.Hello">
        <constructor-arg  name="str" value="yhy"/>
    </bean>
  • 使用下標索引
  <bean id="hello" class="com.yhy.pojo.Hello">
        <!-- 從零開始的索引值,多個參數的時候再使用別的參數 -->
        <constructor-arg index="0" value="hello world"/>
    </bean>

image-20200526151759464

  • 使用參數的類型來配置
  <bean id="hello" class="com.yhy.pojo.Hello">
        <constructor-arg type="java.lang.String" value="hello spring"/>
    </bean>

image-20200526152947985

其他

在.xml配置文件中還有兩個選項。

image-20200526153337576

2、set方法注入

這個方式強調bean類要有set方法,在實例化后調用set方法完成注入。

image-20200526222752373

定義一個person類來測試下set方法注入

注入的類型不同使用的不同參數在配置bean中。如下圖,可以有多個選擇在propety中,一些標簽都是可以直接秒懂的。

image-20200526225254125

  • 常量注入

image-20200526224651374

  • bean注入
 <!-- bean注入 ref進行引入-->
        <property name="address" ref="addr"></property>
  • 數組注入
 <!-- 數組注入 -->
        <property name="books">
            <array>
                <value>悲慘世界</value>
                <value>水滸傳</value>
                <value>金瓶X</value>
            </array>
        </property>
  • 列表注入
    <!-- list注入 -->
        <property name="hobbies">
            <list>
                <value>打籃球</value>
                <value>健身</value>
                <value>游泳</value>
            </list>
        </property>
  • map注入
 <!-- map注入 -->
        <property name="card">
            <map>
                <entry key="銀行卡" value="82937472389"></entry>
                <entry key="身份證" value="2345382937472389"></entry>
            </map>
        </property>
  • properties注入
 <!-- properties注入 -->
        <property name="info">
            <props>
                <prop key="id">201705239</prop>
                <prop key="url">yhytj.top</prop>
                <prop key="name">yhy</prop>
            </props>
        </property>

最后的測試類

    public void test() {
        // 獲得spring的上下文內容
        // 拿到容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 使用容器獲得對象
        Person person = (Person) context.getBean("person");
//這里定義了一個show方法,輸出格式,vscode自動生成tostring還不熟。使用插件生成這個
        person.show();
    }

image-20200526232536118

  • 最后輸出

image-20200526232613109

拓展命名空間

在官網上還可以使用p命名空間c命名空間簡化工作,但其實有idea開發等工具,有時也差不多了,大家可以多多了解下,我只是用了個小測試來了解。

image-20200527092515079

image-20200527092439190

image-20200527092935559

還有一個c命名空間,對應着constructor-arg,這里就不走小demo,可以上官網了解一些


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM