Spring依賴註入(DI)兩種方式的示例詳解

一、依賴註入方式

思考:向一個類中傳遞數據的方式有幾種?

  • 普通方法(set方法)
  • 構造方法

思考:依賴註入描述瞭在容器中建立bean與bean之間依賴關系的過程,如果bean運行需要的是數字或字符串呢?

  • 引用類型
  • 簡單類型(基本數據類型與String)

依賴註入方式:

setter註入

  • 簡單類型
  • 引用類型

構造器註入

  • 簡單類型
  • 引用類型

二、setter註入

引用類型

在bean中定義引用類型屬性並提供可訪問的set方法

import com.itheima.dao.BookDao;
import com.itheima.service.BookService;
 
public class BookServiceImpl implements BookService {
    private BookDao bookDao;
 
    public void save() {
        System.out.println("book service save ...");
        bookDao.save();
    }
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }
}

配置中使用property標簽ref屬性註入引用類型對象

<!--註入引用類型-->
    <bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <!--property標簽:設置註入屬性-->
        <!--name屬性:設置註入的屬性名,實際是set方法對應的名稱-->
        <!--ref屬性:設置註入引用類型bean的id或name-->
        <property name="bookDao" ref="bookDao"/>
        <property name="userDao" ref="userDao"/>
    </bean>

簡單類型

BookDaoImpl實現類:

在bean中定義引用類型屬性並提供可訪問的set方法

import com.itheima.dao.BookDao;
 
public class BookDaoImpl implements BookDao {
 
    private String databaseName;
    private int connectionNum;
 
    //setter註入需要提供要註入對象的set方法
    public void setConnectionNum(int connectionNum) {
        this.connectionNum = connectionNum;
    }
 
    //setter註入需要提供要註入對象的set方法
    public void setDatabaseName(String databaseName) {
        this.databaseName = databaseName;
    }
 
    public void save() {
        System.out.println("book dao save ..." + databaseName + "," + connectionNum);
    }
}

applicationContext.xml配置:

配置中使用property屬性value註入簡單類型對象

<!--註入簡單類型-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <!--property標簽:設置註入屬性-->
        <!--name屬性:設置註入的屬性名,實際是set方法對應的名稱-->
        <!--value屬性:設置註入簡單類型數據值-->
        <property name="connectionNum" value="100"/>
        <property name="databaseName" value="mysql"/>
    </bean>

三、構造器註入

引用類型

在bean中定義引用類型屬性並提供可訪問的構造方法

public class BookServiceImpl implements BookService{
    private BookDao bookDao;
    private UserDao userDao;
 
    public BookServiceImpl(BookDao bookDao, UserDao userDao) {
        this.bookDao = bookDao;
        this.userDao = userDao;
    }
}

配置中使用constructor-arg標簽ref屬性註入引用類型對象

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/>
<bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/>
 
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl">
        <constructor-arg name="userDao" ref="userDao"/>
        <constructor-arg name="bookDao" ref="bookDao"/>
    </bean>

簡單類型

在bean中定義引用類型屬性並提供可訪問的構造方法

public class BookDaoImpl implements BookDao {
    private String databaseName;
    private int connectionNum;
 
    public BookDaoImpl(String databaseName, int connectionNum) {
        this.databaseName = databaseName;
        this.connectionNum = connectionNum;
    }
}

配置中使用constructor-arg標簽ref屬性註入引用類型對象

<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <!--根據構造方法參數名稱註入-->
        <constructor-arg name="connectionNum" value="10"/>
        <constructor-arg name="databaseName" value="mysql"/>
 </bean>

參數適配(瞭解)

配置中使用constructor-arg標簽type屬性註入引用類型對象

<!--解決形參名稱的問題,與形參名不耦合-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <!--根據構造方法參數類型註入-->
        <constructor-arg type="int" value="10"/>
        <constructor-arg type="java.lang.String" value="mysql"/>
    </bean>

配置中使用constructor-arg標簽index屬性註入引用類型對象

 <!--解決參數類型重復問題,使用位置解決參數匹配-->
    <bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl">
        <!--根據構造方法參數位置註入-->
        <constructor-arg index="0" value="mysql"/>
        <constructor-arg index="1" value="100"/>
    </bean>

四、依賴註入方式選擇

1、強制依賴使用構造器進入,使用setter註入有概率不進入註入導致null對象出現

2、可選依賴使用setter註入進行,靈活性強

3、Spring框架倡導使用構造器,第三方框架內部大多數采用構造器註入的形式進行數據初始化,相對嚴謹

4、如果有必要可以兩者同時使用,使用構造器註入完成強制依賴的註入,使用setter註入完成可依賴的註入

5、實際開發過程中還要根據實際情況分析,如果受控對象沒有提供setter方法就必須使用構造器註入

6、自己開發的模塊推薦使用setter註入

到此這篇關於Spring依賴註入(DI)兩種方式的示例詳解的文章就介紹到這瞭,更多相關Spring依賴註入內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: