天天看點

SpringDI四種依賴注入方式詳解SpringDI(依賴注入)

文章目錄

  • SpringDI(依賴注入)
      • 一、DI概述
      • 二、什麼是DI
        • 2.1 了解DI的思想
        • 2.2 依賴
        • 2.3 注入
      • 三、注入方式
        • 3.1 Setter方法注入
          • 3.1.1 定義JavaBean
          • 3.1.2 注入各種資料類型
          • 3.1.3 注入自建類型資料
        • 3.2 構造方法注入
          • 3.2.1 定義JavaBean
          • 3.2.2 構造方法注入
        • 3.3 自動注入
          • 3.3.1 注入場景
          • 3.3.2 自動注入的兩種方式
        • 3.4 注解自動注入
SpringDI四種依賴注入方式詳解SpringDI(依賴注入)

文章已托管到GitHub,大家可以去GitHub檢視閱讀,歡迎老闆們前來Star!

搜尋關注微信公衆号 【碼出Offer】 領取各種學習資料!

SpringDI(依賴注入)

一、DI概述

Dependency Injection即為依賴注入,簡稱DI 。

簡單來說,在Spring建立對象的同時,為其屬性指派,稱之為依賴注入。

形象來說,元件之間依賴關系由容器在運作期決定的,即由容器動态的将某個依賴關系注入到元件之中。

二、什麼是DI

2.1 了解DI的思想

簡單了解了DI(依賴注入),在看依賴注入這個詞,我們也可以将依賴注入以IOC(控制反轉)的形式拆分它。

顧名思義,依賴注入是由“依賴”和“注入”兩個詞彙組合而成,那麼我們再一次順藤摸瓜,分别分析這兩個詞語!

2.2 依賴

依賴一詞,可以拆分成很多元素。比如說,達成依賴條件必須是兩個對象 ,誰依賴誰 ,某一個對象依賴另一個對象的什麼 。這裡我們可以根據這幾個條件列舉出這幾種情況:
  1. 關于誰依賴與誰,當然是應用程式依賴于IOC容器。因為應用程式依賴于IOC容器提供的對象所需外部資源,是以就産生了這種依賴關系。(可以了解為入口,雖然不是這麼嚴謹吧!)

2.3 注入

注入一次,可以也可以拆分成很多元素。比如說,注入可以分解成誰注入誰 ,注入了什麼 。這裡我們也可以根據這兩個條件來列舉出這幾種情況:
  1. 關于誰注入誰,身為容器的IOC肯定是被注入的對象,也就是說我們将所需要的對象注入到IOC容器中。至于注入了什麼,很明顯,就是我們項目中所需要的對象、資源、資料等等。簡單來說,我們需要外部的資源既可以注入到IOC容器中,并由IOC容器來實作注入對象的控制反轉!
  2. IOC的是在系統運作中,動态的向某個對象提供它所需要的其他對象。這一點是通過DI(Dependency Injection,依賴注入)來實作的。

三、注入方式

3.1 Setter方法注入

Setter方法注入,它隻需要提供對應的Setter方法接口實作注入,由于JavaBean一般都實作了Setter方法,是以Setter方法注入也成為了我們常用的注入方法之一。
3.1.1 定義JavaBean
定義一個JavaBean并賦予其Setter方法
package com.mylifes1110.bean;

import java.util.*;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

//[email protected]注解提供了Setter方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer             id;
    private String              password;
    private String              sex;
    private Integer             age;
    private Date                bornDate;
    private String[]            hobbys;
    private Set<String>         phones;
    private List<String>        names;
    private Map<String, String> countries;
    private Properties          files;
}
           
3.1.2 注入各種資料類型
注意:Spring底層對Date日期類型做了處理,預設處理格式為“yyyy/MM/dd”
<bean id="User" class="com.mylifes1110.bean.User">
    <!--注入基本資料類型-->
    <property name="id" value="1"/>
    <property name="password" value="123456"/>
    <property name="sex" value="male"/>
    <property name="age" value="18"/>
    <!--注入日期類型-->
    <property name="bornDate" value="1999/09/09"/>
    <!--注入數組類型-->
    <property name="hobbys">
        <array>
            <value>Run</value>
            <value>Jump</value>
            <value>Climb</value>
        </array>
    </property>
    <!--注入List集合類型-->
    <property name="names">
        <list>
            <value>Ziph</value>
            <value>Join</value>
            <value>Marry</value>
        </list>
    </property>
    <!--注入Set集合類型-->
    <property name="phones">
        <set>
            <value>110</value>
            <value>119</value>
            <value>120</value>
        </set>
    </property>
    <!--注入Properties類型-->
    <property name="files">
        <props>
            <prop key="first">One</prop>
            <prop key="second">Two</prop>
            <prop key="third">Three</prop>
        </props>
    </property>
    <!--注入Map集合類型-->
    <property name="countries">
        <map>
            <entry key="CHINA" value="中國"/>
            <entry key="USA" value="美國"/>
            <entry key="UK" value="英國"/>
        </map>
    </property>
</bean>
           
3.1.3 注入自建類型資料
将Service層需要一個Dao層實作類對象,我們可以使用注入方式來實作對Service層和Dao層的對象關聯
<bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
<bean id="UserService" class="com.mylifes1110.service.impl.UserServiceImpl">
    <property name="userDao" ref="UserDao"/>
</bean>
           
将建立的Bean對象注入到另一個對象中,比如一個JavaBean對象中作為了另一個JavaBean對象的屬性
<!--次要bean,被作為屬性-->
<bean id="address" class="com.mylifes1110.bean.Address">
    <property name="position" value="上海市" />
    <property name="zipCode" value="100001" />
</bean>

<!--主要bean,操作的主體-->
<bean id="user" class="com.mylifes1110.bean.User">
    <!--address屬性引用address對象-->
    <property name="address" ref="address" />
</bean>
           

3.2 構造方法注入

建立對象時,Spring工廠會通過構造方法為對象的屬性指派。由于某些架構或者項目中并沒有為JavaBean提供Setter方法,我們就可以利用其構造方法來注入。不要和我說,沒有提供構造方法哈!(開個玩笑!)
3.2.1 定義JavaBean
定義一個JavaBean對象,為其提供構造方法
public class Student {
    private Integer id;
    private String name;
    private String sex;
    private Integer age;
  
    //Constructors
  	public Student(Integer id , String name , String sex , Integer age){
      	this.id = id;
    	this.name = name;
  	    this.sex = sex;
	    this.age = age;
    }
}
           
3.2.2 構造方法注入
<!--構造注入-->
<bean id="u3" class="com.mylifes1110.bean.Student">
    <!-- 除标簽名稱有變化,其他均和Set注入一緻 -->
    <constructor-arg name="id" value="1234" /> 
    <constructor-arg name="name" value="tom" />
    <constructor-arg name="age" value="20" />
    <constructor-arg name="sex" value="male" />
</bean>
           

3.3 自動注入

不用在配置中 指定為哪個屬性指派,及賦什麼值。由spring自動根據某個 “原則” ,在工廠中查找一個bean,為屬性注入屬性值。
3.3.1 注入場景
将Dao層實作類對象注入到Service層并調用方法得以測試
package com.mylifes1110.service.impl;

import com.mylifes1110.bean.User;
import com.mylifes1110.dao.UserDao;
import com.mylifes1110.service.UserService;

public class UserServiceImpl implements UserService {
    private UserDao userDao;

    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public int insertUser(User user) {
        System.out.println("------insertUser and UserService------");
        return userDao.insertUser(null);
    }
}
           
3.3.2 自動注入的兩種方式
基于名稱自動注入值
<bean id="UserDao" class="com.mylifes1110.dao.impl.UserDaoImpl"/>
	<!--為UserServiceImpl中的屬性基于名稱自動注入值-->
	<bean id="userService" class="com.mylifes1110.service.impl.userServiceImpl" autowire="byName"/>
</beans>
           
基于類型自動注入值,根據實作的接口來判斷并自動注入值,如果實作此接口的實作類太多,它會在很多實作此接口的實作類中選擇名字相同的實作類進行注入。(現根據判斷,如果不成功,則根據名稱注入)
<bean id="userDao" class="com.mylifes1110.dao.UserDaoImpl" />
	<!--為UserServiceImpl中的屬性基于類型自動注入值-->
	<bean id="userService" class="com.mylifes1110.service.impl.UserServiceImpl" autowire="byType"/>
</beans>
           

3.4 注解自動注入

注解名稱 描述
@Autowired 基于類型自動注入
@Resource 基于名稱自動注入
@Qualifier(“userDAO”) 限定要自動注入的bean的id,一般和@Autowired聯用
@Value 注入簡單類型資料 (jdk8種基本資料類型+String類型)
使用基于類型自動注入,将Dao層注入到Service層
@Service
public class UserServiceImpl implements UserService {   
    @Autowired //注入類型為UserDao的bean
    @Qualifier("userDao") //如果有多個類型為UserDao的bean,可以用此注解從中指定一個
    private UserDao userDao;
}
           
使用基于名稱自動注入,将Dao層注入到Serivce層
@Service
public class UserServiceImpl implements UserService {   
    @Resource("userDao") //注入id=“userDao”的bean
    private UserDao userDao;
}
           
使用注入簡單類型資料注解來完成簡單注入JavaBean
public class User{
    @Value("1")    //注入數字
    private Integer id;
    @Value("Ziph") //注入String
	private String name;
}
           
SpringDI四種依賴注入方式詳解SpringDI(依賴注入)