Spring之IOC&DI的差異

學習Spring知識之前,A類中需要使用到B類的對象,我們會怎麼辦呢?

當A類需要使用到B類的資源的話,會直接在A類中創建B類的對象

學習Spring知識之後,A類中需要使用到B類的對象,我們會怎麼辦呢?

 當A類需要使用到B類的資源的話,IOC/DI容器會先去獲得B類的實例(①)

IOC/DI容器再將B類的實例注入到A類中(②)

我們已經看到了容器存在的意義,就是先將程序內所有會使用到的資源全部獲取到,誰需要就再給誰!

這裏又提到了IOC和DI,那麼二者之間又有什麼區別呢?

什麼是IOC?

IOC(Inversion Of Control):控制反轉,意思就是將獲取資源的權利由應用程序轉變爲了Spring容器

什麼是DI?

DI( Dependency Injection):依賴注入,意思就是Spring容器獲取資源並將資源注入到應用程序中

二者的區別

二者是對同一件事情的不同描述,只是描述時所站的角度不同罷了

下面會介紹下依賴注入的幾種類型!

一.案例展示

1.測試準備

項目工程

2.代碼展示

***pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.howie</groupId>
    <artifactId>springIOC_injection</artifactId>
    <version>1.0-SNAPSHOT</version>
    
    <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--導入Spring-context的jar包-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
    </dependencies>
</project>

***ComplexTypeInject.java

package com.howie.pojo;

import java.util.*;

/**
 * @Author weihuanwen
 * @Date 2019/8/14 23:49
 * @Version 1.0
 */
public class ComplexTypeInject {
    private String[] myStrs;
    private List<String> myList;
    private Set<String> mySet;
    private Map<String,String> myMap;
    private Properties myProps;

    public String[] getMyStrs() {
        return myStrs;
    }

    public void setMyStrs(String[] myStrs) {
        this.myStrs = myStrs;
    }

    public List<String> getMyList() {
        return myList;
    }

    public void setMyList(List<String> myList) {
        this.myList = myList;
    }

    public Set<String> getMySet() {
        return mySet;
    }

    public void setMySet(Set<String> mySet) {
        this.mySet = mySet;
    }

    public Map<String, String> getMyMap() {
        return myMap;
    }

    public void setMyMap(Map<String, String> myMap) {
        this.myMap = myMap;
    }

    public Properties getMyProps() {
        return myProps;
    }

    public void setMyProps(Properties myProps) {
        this.myProps = myProps;
    }

    @Override
    public String toString() {
        return "ComplexTypeInject{" +
                "myStrs=" + Arrays.toString(myStrs) +
                ", myList=" + myList +
                ", mySet=" + mySet +
                ", myMap=" + myMap +
                ", myProps=" + myProps +
                '}';
    }
}

***UserByConstructorInject.java

package com.howie.pojo;

/**
 * @Author weihuanwen
 * @Date 2019/8/14 23:48
 * @Version 1.0
 */
public class UserByConstructorInject {

    private String name;
    private Integer age;

    public UserByConstructorInject(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserByConstructorInject{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

***UserBySetInject.java

package com.howie.pojo;

/**
 * @Author weihuanwen
 * @Date 2019/8/14 23:45
 * @Version 1.0
 */
public class UserBySetInject {

    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "UserBySetInject{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

***ApplicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--通過實體類的setter方法實現屬性值注入-->
    <bean id="UserBySetInject" class="com.howie.pojo.UserBySetInject">
        <!--使用property標籤完成實體類的set()操作-->
        <property name="name" value="Jhon" />
        <property name="age" value="28" />
    </bean>

    <!--通過構造方法實現屬性值注入-->
    <bean id="UserByConstructorInject" class="com.howie.pojo.UserByConstructorInject">
        <!--使用constructor標籤完成實體類構造方法屬性注入-->
        <constructor-arg name="name" value="Lily" />
        <constructor-arg name="age" value="30" />
    </bean>

    <!--實現複雜類型注入的配置-->
    <bean id="ComplexTypeInject" class="com.howie.pojo.ComplexTypeInject">
        <!--String[] myStrs-->
        <property name="myStrs">
            <array>
                <value>孫悟空</value>
                <value>菩提祖</value>
                <value>紅孩兒</value>
            </array>
        </property>
        <!--List<String> myList;-->
        <property name="myList">
            <list>
                <value>浮誇</value>
                <value>十年</value>
                <value>揹包</value>
            </list>
        </property>
        <!--Set<String> mySet;-->
        <property name="mySet">
            <set>
                <value>若需</value>
                <value>若即</value>
                <value>若離</value>
            </set>
        </property>
        <!--Map<String,String> myMap;-->
        <property name="myMap">
            <map>
                <entry key="天" value="地" />
                <entry key="雨" value="風" />
                <entry key="大陸" value="長空" />
            </map>
        </property>
        <!--Properties myProps;-->
        <property name="myProps">
            <props>
                <prop key="1">未來</prop>
                <prop key="2">現在</prop>
            </props>
        </property>
    </bean>
</beans>

***MyTest.java

package com.howie;

import com.howie.pojo.ComplexTypeInject;
import com.howie.pojo.UserByConstructorInject;
import com.howie.pojo.UserBySetInject;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author weihuanwen
 * @Date 2019/8/14 23:52
 * @Version 1.0
 */
public class MyTest {
    private ClassPathXmlApplicationContext cpxax;
    @Before
    public void execBefore(){
        cpxax = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    }

    @Test
    public void testSetInject(){
        UserBySetInject user = cpxax.getBean("UserBySetInject", UserBySetInject.class);
        System.out.println(user);
    }

    @Test
    public void testConstructorInject(){
        UserByConstructorInject user = cpxax.getBean("UserByConstructorInject", UserByConstructorInject.class);
        System.out.println(user);
    }

    @Test
    public void testComplexInject(){
        ComplexTypeInject cti = cpxax.getBean("ComplexTypeInject", ComplexTypeInject.class);
        System.out.println(cti);
    }
}

3.測試

①執行testSetInject()控制檯輸出

UserBySetInject{name='Jhon', age=28}

②執行testConstructorInject()控制檯輸出

UserByConstructorInject{name='Lily', age=30}

③執行testComplexInject()控制檯輸出

ComplexTypeInject{myStrs=[孫悟空, 菩提祖, 紅孩兒], myList=[浮誇, 十年, 揹包], mySet=[若需, 若即, 若離], myMap={天=地, 雨=風, 大陸=長空}, myProps={2=現在, 1=未來}}

二.總結

1.通過上面的案例,可以瞭解到如何實現下面的注入

  • set注入
  • 構造注入
  • 複雜類型注入

2.爲什麼要是用Spring呢?

在一個大型的應用程序中必然包含很多的組件,組件之間互相調用,但是在運行時並非所有的組件都必須創建.在沒有Spring技術之前,A組件需要調用B組件時,就需要採取new或者getInstance的方式獲取B組件的實例,這樣就產生了組件A同組件B之間的耦合.隨着工程規模的擴大, N多組件間的耦合度越來越高,後期維護成本相當高.爲了減少這種耦合,Spring誕生了!

Spring框架基於BeanFactory,將模塊的配置信息(模塊根據需求創建)同模塊的配置參數(模塊不必讀取參數,Spring統一加載)統一管理.加入依賴注入(DI),Spring負責將模塊依賴度的其他模塊(push)推送進來,而不是自己去拉取(pull),所以是一個"控制反轉"(IOC)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章