詳解Spring DI依賴注入的方式和類型
一、什么是依賴注入
依賴注入(Dependency Injection,簡稱DI),它是Spring控制反轉(zhuǎn)思想的具體實(shí)現(xiàn)。 控制反轉(zhuǎn)將對象的創(chuàng)建交給了Spring,但是對象中可能會(huì)依賴其他對象。比如service類中要有dao類的屬性,我們稱service依賴于dao。之前需要手動(dòng)注入屬性值,代碼如下:
public interface StudentDao { Student findById(int id); } public class StudentDaoImpl implements StudentDao{ @Override public Student findById(int id) { // 模擬根據(jù)id查詢學(xué)生 return new Student(1,"程序員","北京"); } } public class StudentService { // service依賴dao,手動(dòng)注入屬性值,即手動(dòng)維護(hù)依賴關(guān)系 private StudentDao studentDao = new StudentDaoImpl(); public Student findStudentById(int id){ return studentDao.findById(id); } }
此時(shí),當(dāng)StudentService的想要使用StudentDao的另一個(gè)實(shí)現(xiàn)類如StudentDaoImpl2時(shí),則需要修改Java源碼,造成代碼的可維護(hù)性降低。
而使用Spring框架后,Spring管理Service對象與Dao對象,此時(shí)它能夠?yàn)镾ervice對象注入依賴的Dao屬性值。這就是Spring的依賴注入。簡單來說,控制反轉(zhuǎn)是創(chuàng)建對象,依賴注入是為對象的屬性賦值
二、依賴注入方式
1. Setter注入
被注入類編寫屬性的setter方法
public void setStudentDao(StudentDao studentDao){ this.studentDao = studentDao; }
配置文件中,給需要注入屬性值的 <bean> 中設(shè)置 <property>
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"> </bean> <bean id="studentService" class="com.itbaizhan.service.StudentService"> <!--依賴注入--> <!--name:對象的屬性名 ref:容器中對象的id值--> <property name="studentDao" ref="studentDao"></property> </bean>
測試
新增測試方法
// 測試依賴注入 @Test public void t6(){ ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); StudentService service = (StudentService) ac.getBean("studentService"); System.out.println(service.findStudentById(8)); }
運(yùn)行結(jié)果
OK,確實(shí)成功測試到了
2. 構(gòu)造方法注入
被注入類編寫有參的構(gòu)造方法
public StudentService(StudentDao studentDao){ this.studentDao = studentDao; }
給需要注入屬性值的 <bean> 中設(shè)置 <constructor-arg>
<bean id="studentDao" class="com.itbaizhan.dao.StudentDaoImpl"></bean> <bean id="studentService" class="com.itbaizhan.service.StudentService"> <!-- 依賴注入 --> <!-- name:對象的屬性名 ref:配置文件中注入對象的id值 --> <constructor-arg name="studentDao" ref="studentDao"></constructor-arg> </bean>
測試結(jié)果:
OK,確實(shí)也是可以使用的
3. 自動(dòng)注入
自動(dòng)注入不需要在 <bean> 標(biāo)簽中添加其他標(biāo)簽注入屬性值,而是自動(dòng)從容器中找到相應(yīng)的bean對象設(shè)置為屬性值。
自動(dòng)注入有兩種配置方式:
- 全局配置:在 <beans> 中設(shè)置 default-autowire 屬性可以定義所有bean對象的自動(dòng)注入策略。
- 局部配置:在 <bean> 中設(shè)置 autowire 屬性可以定義當(dāng)前bean對象的自動(dòng)注入策略。
autowire的取值如下:
- no:不會(huì)進(jìn)行自動(dòng)注入。
- default:全局配置default相當(dāng)于no,局部配置default表示使用全局配置
- byName:在Spring容器中查找id與屬性名相同的bean,并進(jìn)行注入。需要提供set方法。
- byType:在Spring容器中查找類型與屬性類型相同的bean,并進(jìn)行注入。需要提供set方法。
- constructor:在Spring容器中查找id與屬性名相同的bean,并進(jìn)行注入。需要提供構(gòu)造方法。
三、依賴注入類型
DI支持注入bean類型、基本數(shù)據(jù)類型和字符串、List集合、Set集合、Map集合、Properties對象類型等,他們的寫法如下:
準(zhǔn)備注入屬性的類
package com.example.service; import com.example.dao.StudentDao; import com.example.pojo.Student; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class StudentService { // service依賴dao,手動(dòng)注入屬性值,即手動(dòng)維護(hù)依賴關(guān)系 //private StudentDao studentDao; // bean屬性 private StudentDao studentDao; // 字符串類型 private String name; // 基本數(shù)據(jù)類型 private int count; // 字符串List集合 private List<String> students1; // 對象類型List集合 private List<Student> nameList; // 字符串類型Set集合 private Set<String> students2; // 字符串類型Map集合 private Map<String, String> students3; // 對象類型map集合 private Map<String,Student> studentMap; // Properties類型 private Properties properties; public StudentService(){} public StudentService(StudentDao studentDao){ this.studentDao = studentDao; } public Student findStudentById(int id){ return studentDao.findById(id); } public void setStudentDao(StudentDao studentDao){ this.studentDao = studentDao; } public StudentDao getStudentDao() { return studentDao; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getCount() { return count; } public void setCount(int count) { this.count = count; } public List<String> getStudents1() { return students1; } public void setStudents1(List<String> students1) { this.students1 = students1; } public Set<String> getStudents2() { return students2; } public void setStudents2(Set<String> students2) { this.students2 = students2; } public Map<String, String> getNames2() { return students3; } public void setNames2(Map<String, Student> names2) { this.studentMap = names2; } public Map<String, String> getStudents3() { return students3; } public void setStudents3(Map<String, String> students3) { this.students3 = students3; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public List<Student> getNameList() { return nameList; } public void setNameList(List<Student> nameList) { this.nameList = nameList; } @Override public String toString() { return "StudentService[ " + "studentDao=" + studentDao + ", name='" + name + '\'' + ", count=" + count + ", students1=" + students1 + ", nameList=" + nameList + ", students2=" + students2 + ", students3=" + students3 + ", studentMap=" + studentMap + ", properties=" + properties + " ]"; } }
準(zhǔn)備測試方法
// 測試注入類型 @Test public void t7(){ ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml"); StudentService service = (StudentService) ac.getBean("studentService"); System.out.println(service); }
1. 注入bean類型
<!-- 注入bean類型 --> <bean id="studentDao" class="com.example.dao.StudentDaoImpl1"/> <!-- 寫法1 --> <bean id="studentService" class="com.example.service.StudentService"> <property name="studentDao" ref="studentDao"/> </bean> <!-- 寫法2 --> <!--<bean id="studentService" class="com.example.service.StudentService"> <property name="studentDao"> <ref bean="studentDao"/> </property> </bean>-->
2. 注入基本數(shù)據(jù)類型
<!-- 注入基本數(shù)據(jù)類型 --> <!-- 寫法一 name:屬性名 value:屬性值 --> <property name="name" value="程序員"/> <!-- 寫法二 name:屬性名 value:屬性值--> <property name="count"> <value>10</value> </property>
3. 注入List集合
<!-- 注入List集合 --> <!-- 簡單的數(shù)據(jù)類型List集合 name:屬性名 --> <property name="students1" > <list> <value>上海</value> <value>廣州</value> </list> </property> <!-- 對象類型的List集合 name:屬性名 --> <property name="nameList"> <list> <bean class="com.example.pojo.Student"> <property name="id" value="1"/> <property name="name" value="幾何心涼"/> <property name="address" value="北京"/> </bean> <bean class="com.example.pojo.Student"> <property name="id" value="2"/> <property name="name" value="哈士奇"/> <property name="address" value="上海"/> </bean> </list> </property>
4. 注入Set集合
<!-- 注入Set集合 --> <property name="students2"> <set> <value>深圳</value> <value>北京</value> </set> </property>
5. 注入Map集合
<!-- 注入Map集合 --> <property name="students3"> <map> <entry key="哈士奇" value="上海"/> <entry key="幾何心涼" value="北京"/> </map> </property> <!-- 注入對象類型map類型 --> <property name="names2"> <map> <entry key="student1" value-ref="s1"/> <entry key="student2" value-ref="s2"/> </map> </property>
<bean id="s1" class="com.example.pojo.Student"> <property name="id" value="1"/> <property name="name" value="幾何心涼"/> <property name="address" value="北京"/> </bean> <bean id="s2" class="com.example.pojo.Student"> <property name="id" value="2"/> <property name="name" value="哈士奇"/> <property name="address" value="上海"/> </bean>
上面是用到的bean對象
6. 注入Properties對象
<!-- 注入properties --> <property name="properties"> <props> <prop key="配置1">值1</prop> <prop key="配置2">值2</prop> </props> </property>
運(yùn)行測試方法測試一下
OK ,可以看到都是插入的了。
到此這篇關(guān)于詳解Spring DI依賴注入的方式和類型的文章就介紹到這了,更多相關(guān)Spring DI依賴注入 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring中異步注解@Async的使用、原理及使用時(shí)可能導(dǎo)致的問題及解決方法
這篇文章主要介紹了Spring中異步注解@Async的使用、原理及使用時(shí)可能導(dǎo)致的問題及解決方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07java解析dbf之通過javadbf包生成和讀取dbf文件
這篇文章主要介紹了java通過javadbf讀取和生成DBF文件的方法,大家參考使用吧2014-01-01spring cloud gateway集成hystrix實(shí)戰(zhàn)篇
這篇文章主要介紹了spring cloud gateway集成hystrix實(shí)戰(zhàn),具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07Ribbon單獨(dú)使用,配置自動(dòng)重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式
這篇文章主要介紹了Ribbon單獨(dú)使用,配置自動(dòng)重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12Spring Data JPA進(jìn)行數(shù)據(jù)分頁與排序的方法
這篇文章主要介紹了Spring Data JPA進(jìn)行數(shù)據(jù)分頁與排序的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11SpringBoot消息國際化配置實(shí)現(xiàn)過程解析
這篇文章主要介紹了SpringBoot消息國際化配置實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07springboot+redis實(shí)現(xiàn)簡單的熱搜功能
這篇文章主要介紹了springboot+redis實(shí)現(xiàn)一個(gè)簡單的熱搜功能,通過代碼介紹了過濾不雅文字的過濾器,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05