天天看點

Spring DI(依賴注入)之xml配置

前言

​ 通過IOC控制反轉的學習,我們已經知道了如果将類的建立進行控制反轉,并使用Spring容器來管理;也知道了如何建立Spring容器,從中擷取Bean。

​ 但是當我們一個類中定義了其他基本類型或引用類型的屬性,那麼怎麼在從Spring容器中擷取Bean的同時,也能夠讓Bean中的屬性賦上值呢?

​ 這就是我們要學習的DI依賴注入。

依賴注入簡介

當某個角色(可能是一個Java執行個體,調用者)需要另一個角色(另一個Java執行個體,被調用者)的協助時,在 傳統的程式設計過程中,通常由調用者來建立被調用者的執行個體。

但在Spring裡,建立被調用者的工作不再由調用者來完成,是以稱為控制反轉;建立被調用者執行個體的工作通常由Spring容器來完成,然後注入調用者,是以也稱為依賴注入。

簡而言之,依賴注入就是在Spring容器中擷取一個Bean的同時,讓這個Bean中需要的屬性、參數也能擷取到對應的值。

依賴注入的方式

  1. 通過構造方法進行注入
  2. 通過set方法進行注入

DI入門案例

  • 通過構造方式進行注入
    • User實體類
      /**
       * 使用者實體類
       */
      public class User {
      
          private String name; //姓名
          private int age; //年齡
      
          public User(String name, int age) {
              this.name = name;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
                 
    • applicationContext配置檔案
      <?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">
          
          <!--
      		配置User
      		id:表示此bean的唯一辨別
      		class:指定要建立對象的類的位元組碼對象
      	-->
          <bean id="user" class="com.itheima.entity.User">
              <!--
      			當通過構造方法注入時,使用constructor-arg标簽
      			name:對應構造方法的參數
      			value:對name指定的參數進行指派,無論字元和數字都用雙引号
      		-->
              <constructor-arg name="name" value="張三"/>
              <constructor-arg name="age" value="25"/>
          </bean>
      </beans>
                 
    • 測試代碼
      public class Test {
      
          public static void main(String[] args) {
              //加載配置檔案,建立Spring容器
              ApplicationContext context = new
                      ClassPathXmlApplicationContext("applicationContext.xml");
              //擷取Bean
              User user = context.getBean("user", User.class);
              System.out.println(user);
          }
      }
                 
    • 結果
      Spring DI(依賴注入)之xml配置
  • 通過set方法注入
    • User1實體類
      /**
       * 使用者實體類
       */
      public class User1 {
      
          private String name; //姓名
          private int age; //年齡
      
          public void setName(String name) {
              this.name = name;
          }
      
          public void setAge(int age) {
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "name='" + name + '\'' +
                      ", age=" + age +
                      '}';
          }
      }
      
                 
    • applicationContext.xml配置檔案
      <!--
      	配置User1
      	id:表示此bean的唯一辨別
      	class:指定要建立對象的類的位元組碼對象
      -->
      <bean id="user1" class="com.itheima.entity.User1">
           <!--
             當通過set方法注入時,使用property标簽
             name:對應set方法的方法名(例如setName方法,去掉setN  -> 對應的是:name)
             value:對name指定的參數進行指派,無論字元和數字都用雙引号
       	 -->
          <property name="name" value="李四"/>
          <property name="age" value="56"/>
      </bean>
                 
    • 測試類
      public class Test1 {
      
          public static void main(String[] args) {
              //加載配置檔案,建立Spring容器
              ApplicationContext context = new
                      ClassPathXmlApplicationContext("applicationContext.xml");
              //擷取Bean
              User1 user1 = context.getBean("user1", User1.class);
              System.out.println(user1);
          }
      }
                 
    • 結果
      Spring DI(依賴注入)之xml配置

多種類型依賴注入

屬性類型分類

  • 基本類型包裝類,比如 Integer、Double、Boolean;
  • 字元串類型,比如 String;
  • 集合類型,比如 list、set、map 。
  • 類類型,比如 其餘定義的 java 類;

代碼資料準備

//使用者實體類
public class User {

private Integer id;
private String name;
private Object [] array;
private List    list;
private Map  map;
//省略get和set方法

}

           

以下根據這個實體類來示範各個屬性類型的依賴注入。

基本類型和字元串類型

​ 對于基本類型和字元串類型,在 xml 的配置檔案中,通過 value 屬性即可以指派,在入門案例中已經使用。

數組類型

  • 配置檔案編寫
    <!-- 
    	數組的屬性注入
    	id:設定bean的唯一辨別,擷取Bean的時候根據id進行擷取
    	class:要建立對象的類的位元組碼對象,對象建立後會由Spring進行管理
     -->
    <bean id="user" class="com.offcn.entity.User">
    
    	<property name="array">
    		<array>
    			<value>tom</value>
    			<value>jerry</value>
    		</array>
    	</property>
    </bean>
               
  • 配置解釋
    • property 中的 name Java類中數組的set方法的名字 如:SetArray 去掉Set ,A小寫,得到array;name隻與set方法有關。 property表示通過set方法注入。
    • array 标簽是固定的,不能變化,表示屬性是一個數組,是以加在了 property 的屬性内部。
    • value 表示數組中的值,因為數組可以存儲多個值,是以每一個數組的值,通過一個 value 标簽聲明。

集合類型

  • list集合依賴注入
    • 配置檔案編寫
      <!-- 集合的屬性注入 -->
      <bean id="user" class="com.offcn.entity.User">
      	<property name="list">
      		<list>
      			<value>笑傲江湖</value>
      			<value>俠客行</value>
      			<value>連城訣</value>
      		</list>
      	</property>
      </bean>
                 
    • 配置解釋
      • property 中的 name 是 java 類中List集合的set方法名,表示通過set方法注入,name隻與set方法名有關。
      • list 标簽是固定的,不能變化,表示屬性是一個 list 集合 ,是以加在了 property 的屬性内部
      • value 表示集合中的值,因為集合可以存儲多個值,是以每一個集合中的值,通過一個 value 标簽聲明.
    • List集合與Set集合相同
  • map集合依賴注入
    • 配置檔案編寫
      <bean id="user" class="com.offcn.entity.User">
      	<property name="map">
      		<map>
      			<entry key="小亮" value="小路"></entry>
      			<entry key="文同學" value="伊利姐"></entry>
      		</map>
      	</property>
      </bean>
                 
    • 配置解釋
      • property 中的 name 是 java 類中List集合的set方法名,表示通過set方法注入,name隻與set方法名有關。
      • map 标簽是固定的,不能變化,表示屬性是一個 map 集合 ,是以加在了 property 的屬性内部。
      • entry 标簽固定表示 map 中的一對鍵值對,map 也可以存儲多對,是以 key 表示鍵值對的鍵,value 表示鍵值對的值。

類類型

​ 一個類中依賴另一個類的情況;就像我們編寫三層架構的時候,表現層依賴業務邏輯層,業務邏輯層依賴資料通路層;隻有資料通路層與資料庫打交道。

​ 以下我們就模拟一下 業務邏輯層依賴資料通路層的情況;也就是說在邏輯層中,有資料通路層類的成員變量屬性。

​ 資料準備

  • 資料通路層 UserDao
    /**
     * 模拟關于使用者的資料通路層
     */
    public class UserDao {
    
        /**
         * 模拟儲存使用者
         */
        public void saveUser() {
            System.out.println("我是UserDao中的儲存使用者的方法!");
        }
    }
    
               
  • 業務邏輯層 UserService
    /**
     * 模拟使用者業務邏輯層
     */
    public class UserService {
    
        //依賴資料通路層
        private UserDao userDao;
    
        //提供set方法,友善依賴注入
        public void setUserDao(UserDao userDao) {
            this.userDao = userDao;
        }
    
    
        /**
         * 儲存使用者方法
         */
        public void saveUser() {
            //調用資料通路層的儲存使用者方法
            userDao.saveUser();
        }
    }
               
  • 編寫Spring配置檔案
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:util="http://www.springframework.org/schema/util"
           xsi:schemaLocation="
            http://www.springframework.org/schema/beans https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
    
            <!--先要配置資料通路層UserDao-->
            <bean id="userDao" class="com.my.Dao.UserDao"/>
            
            <!--配置業務邏輯層-->
            <bean id="userService" class="com.my.service.UserService">
                    <!--
                            通過Set方法注入UserDao
                            name:對應UserService類中的Set方法的名字
                            ref:(reference:引用),表示這個屬性引用上面配置的UserDao的id,這樣就能實作類類型的注入
                    -->
                    <property name="userDao" ref="userDao"/>
            </bean>
    </beans>
               
  • 配置說明
    • property:表示通過Set方法進行依賴注入。
    • name:對應UserService類中的Set方法的名字,name隻與Set方法名相關。
    • ref:表示這個屬性引用上面配置的UserDao的id,這樣就能實作類類型的注入,當我們從Spring中擷取UserServices示例對象的時候,Spring會将UserServices對象依賴的UserDao執行個體對象,一并完成依賴注入。
  • 測試代碼
    /**
     * 測試類
     */
    public class UserServiceTest {
    
        /**
         * 儲存使用者方法測試
         */
        @Test
        public void userSaveTest() {
            //建立spring容器,參數指定spring配置檔案的全名
            ApplicationContext context = new
                    ClassPathXmlApplicationContext("applicationContext.xml");
    
            //擷取Bean
            UserService userService = context.getBean("userService", UserService.class);
            
            //調用儲存使用者方法
            userService.saveUser();
    
        }
    }
               
  • 結果
    Spring DI(依賴注入)之xml配置

總結

​ 以上就是Spring的xml配置依賴注入的方式,在xml配置的時候一步一步來,看清楚一個類中依賴了哪些類,然後進行各個類的配置。