Spring DI(依賴注入)之XML配置
1.前言
在第二個整個大章節(jié),我們詳細講解了 控制反轉,也就是對 bean 做實例化的部分。而我們知道 ,Spring 的核心功能是兩個:控制反轉 和 依賴注入。
那么控制反轉我們已經(jīng)講過,而依賴注入是什么呢?
各位看官,隨小可一起來…
2. 依賴注入案例
2.1概念介紹
知識回顧
對于依賴注入,我們在第一章第一節(jié)已經(jīng)介紹過,我們回顧一下
概念解釋
上面是我們之前對于依賴注入的一個通俗解釋。那么這里再著重強調一下 IOC 控制反轉與 DI 依賴注入的關系:
IOC 控制反轉是將對象實例化的動作交由了 Spring 框架, 它的作用是降低了程序的耦合,不需要我們手動的創(chuàng)建對象,但是程序的耦合性還是存在。
對象中肯定會有一些其余對象的引用,那么這種引用就稱呼為對象的依賴,而 DI 依賴注入其實 是 IOC 設計思想的一種表現(xiàn)形式。
對于 這種屬性依賴,我們無需手動賦予,也是講賦值的動作交給 Spring ,那么這種操作就是 依賴注入。
依賴注入方式:
- 第一種方式是通過 xml 配置的方式實現(xiàn);
- 第二種方式是在屬性或者方法上使用注解的方式實現(xiàn)。
那么,本章節(jié)先帶大家體驗下 xml 方式實現(xiàn)依賴注入。
2.2 工程實現(xiàn):
搭建動作介紹
- 創(chuàng)建一個 maven 工程
- 導入Spring 使用的依賴
- 編寫業(yè)務層的 Service 和持久層的 Dao java 類
- 編寫 Spring 的配置文件
創(chuàng)建工程 導入依賴 省略
可以參考之前創(chuàng)建過的IOC工程
java 代碼
創(chuàng)建 Servcie 的接口和接口的實現(xiàn)類,代碼如下:
//接口代碼
public interface UserService {
public void deleteById(Integer id);
}
//實現(xiàn)類代碼
public class UserServiceImpl implements UserService {
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void deleteById(Integer id) {
System.out.println("刪除的方法執(zhí)行");
}
}
UserDao 接口和實現(xiàn)類代碼:
//dao接口代碼
public interface UserDao {
}
//dao實現(xiàn)類代碼
public class UserDaoImpl implements UserDao {
}
代碼解釋: dao的接口和實現(xiàn)類中并沒有方法,只是為了測試 作為service中的屬性依賴,可以實現(xiàn)由 Spring 完成動態(tài)注入。
重點來了:spring 的核心配置文件:
配置解釋:
在上面的配置文件中:
- bean 標簽是描述一個被實例化的類 而 property 則表示一類中的屬性
- property 標簽中的屬性 name 一般我們寫成類中的屬性名稱, 實際上,起決定作用的并不是屬性名,下面示例再展示
- ref 表示當前的屬性 是一個引用對象,而引用的是誰呢? ref 中的值 必須是在容器中已經(jīng)實例化的一個引用對象的唯一標識。
- value 當前的屬性可以直接賦值,所以通過 value 中,填寫要賦予的數(shù)值即可
測試結果
代碼解釋
可以看到 我們得到了 service 中的類屬性 Userdao 的實例,并且也 得到了 字符串屬性 userName的值 zs
2.3 property注入屬性的解釋
剛剛我們在上面的示例中 展示了xml依賴屬性的注入,也是比較好理解。
這里我們強調一下使用的注意事項:
如果是 property 屬性標簽實現(xiàn)屬性注入,那么類中必須由配置在 property 標簽中 name 屬性的 set 方法
下面我們測試一下set方法的改變:
先講 service 中 dao 的 set 方法改造如下:
public void setDao(UserDao userDao) {
System.out.println("執(zhí)行了set方法 給dao屬性賦值");
this.userDao = userDao;
}
這時候代碼中的set方法變成了 setDao 配置文件不變,依然是
<property name="userDao" ref="userDao"></property>
我們看看會產生什么問題
Caused by: org.springframework.beans.NotWritablePropertyException: Invalid property 'userDao' of bean class [com.wyan.service.UserServiceImpl]: Bean property 'userDao' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
at org.springframework.beans.BeanWrapperImpl.createNotWritablePropertyException(BeanWrapperImpl.java:247)
at org.springframework.beans.AbstractNestablePropertyAccessor.processLocalProperty(AbstractNestablePropertyAccessor.java:426)
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:278)
at org.springframework.beans.AbstractNestablePropertyAccessor.setPropertyValue(AbstractNestablePropertyAccessor.java:266)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:97)
at org.springframework.beans.AbstractPropertyAccessor.setPropertyValues(AbstractPropertyAccessor.java:77)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1646)
可以看到異常的堆棧信息 無效的 userDao 屬性, userDao 不可以 或者 沒有有效的 setter 方法提供。
更改xml文件中的 property 標簽的 name 屬性 為 dao
<property name="dao" ref="userDao"></property>
測試結果如下:
所以我們說 property 中的 name 屬性不一定要跟 Java類中的屬性名保持一致 而是必須跟 setter 方法的名稱一致
3.總結:
本章節(jié)重點依賴注入的 xml 實現(xiàn)
- 依賴注入 實際上是 IOC 設計思想的一種具體實現(xiàn)
- 依賴注入 可以通過 xml 配置實現(xiàn) ,可以通過注解實現(xiàn)
- xml 的依賴注入 是依托于類中的 set 方法實現(xiàn)的。
不積跬步無以至千里,不積小流無以成江?!^續(xù)努力