詳解Spring DI依賴(lài)注入的方式和類(lèi)型
一、什么是依賴(lài)注入
依賴(lài)注入(Dependency Injection,簡(jiǎn)稱(chēng)DI),它是Spring控制反轉(zhuǎn)思想的具體實(shí)現(xiàn)。 控制反轉(zhuǎn)將對(duì)象的創(chuàng)建交給了Spring,但是對(duì)象中可能會(huì)依賴(lài)其他對(duì)象。比如service類(lèi)中要有dao類(lèi)的屬性,我們稱(chēng)service依賴(lài)于dao。之前需要手動(dòng)注入屬性值,代碼如下:
public interface StudentDao {
Student findById(int id);
}
public class StudentDaoImpl implements StudentDao{
@Override
public Student findById(int id) {
// 模擬根據(jù)id查詢(xún)學(xué)生
return new Student(1,"程序員","北京");
}
}
public class StudentService {
// service依賴(lài)dao,手動(dòng)注入屬性值,即手動(dòng)維護(hù)依賴(lài)關(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)類(lèi)如StudentDaoImpl2時(shí),則需要修改Java源碼,造成代碼的可維護(hù)性降低。
而使用Spring框架后,Spring管理Service對(duì)象與Dao對(duì)象,此時(shí)它能夠?yàn)镾ervice對(duì)象注入依賴(lài)的Dao屬性值。這就是Spring的依賴(lài)注入。簡(jiǎn)單來(lái)說(shuō),控制反轉(zhuǎn)是創(chuàng)建對(duì)象,依賴(lài)注入是為對(duì)象的屬性賦值
二、依賴(lài)注入方式
1. Setter注入
被注入類(lèi)編寫(xiě)屬性的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"> <!--依賴(lài)注入--> <!--name:對(duì)象的屬性名 ref:容器中對(duì)象的id值--> <property name="studentDao" ref="studentDao"></property> </bean>
測(cè)試
新增測(cè)試方法
// 測(cè)試依賴(lài)注入
@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í)成功測(cè)試到了
2. 構(gòu)造方法注入
被注入類(lèi)編寫(xiě)有參的構(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"> <!-- 依賴(lài)注入 --> <!-- name:對(duì)象的屬性名 ref:配置文件中注入對(duì)象的id值 --> <constructor-arg name="studentDao" ref="studentDao"></constructor-arg> </bean>
測(cè)試結(jié)果:

OK,確實(shí)也是可以使用的
3. 自動(dòng)注入
自動(dòng)注入不需要在 <bean> 標(biāo)簽中添加其他標(biāo)簽注入屬性值,而是自動(dòng)從容器中找到相應(yīng)的bean對(duì)象設(shè)置為屬性值。
自動(dòng)注入有兩種配置方式:
- 全局配置:在 <beans> 中設(shè)置 default-autowire 屬性可以定義所有bean對(duì)象的自動(dòng)注入策略。
- 局部配置:在 <bean> 中設(shè)置 autowire 屬性可以定義當(dāng)前bean對(duì)象的自動(dòng)注入策略。
autowire的取值如下:
- no:不會(huì)進(jìn)行自動(dòng)注入。
- default:全局配置default相當(dāng)于no,局部配置default表示使用全局配置
- byName:在Spring容器中查找id與屬性名相同的bean,并進(jìn)行注入。需要提供set方法。
- byType:在Spring容器中查找類(lèi)型與屬性類(lèi)型相同的bean,并進(jìn)行注入。需要提供set方法。
- constructor:在Spring容器中查找id與屬性名相同的bean,并進(jìn)行注入。需要提供構(gòu)造方法。
三、依賴(lài)注入類(lèi)型

DI支持注入bean類(lèi)型、基本數(shù)據(jù)類(lèi)型和字符串、List集合、Set集合、Map集合、Properties對(duì)象類(lèi)型等,他們的寫(xiě)法如下:
準(zhǔn)備注入屬性的類(lèi)
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依賴(lài)dao,手動(dòng)注入屬性值,即手動(dòng)維護(hù)依賴(lài)關(guān)系
//private StudentDao studentDao;
// bean屬性
private StudentDao studentDao;
// 字符串類(lèi)型
private String name;
// 基本數(shù)據(jù)類(lèi)型
private int count;
// 字符串List集合
private List<String> students1;
// 對(duì)象類(lèi)型List集合
private List<Student> nameList;
// 字符串類(lèi)型Set集合
private Set<String> students2;
// 字符串類(lèi)型Map集合
private Map<String, String> students3;
// 對(duì)象類(lèi)型map集合
private Map<String,Student> studentMap;
// Properties類(lèi)型
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)備測(cè)試方法
// 測(cè)試注入類(lèi)型
@Test
public void t7(){
ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
StudentService service = (StudentService) ac.getBean("studentService");
System.out.println(service);
}1. 注入bean類(lèi)型
<!-- 注入bean類(lèi)型 -->
<bean id="studentDao" class="com.example.dao.StudentDaoImpl1"/>
<!-- 寫(xiě)法1 -->
<bean id="studentService" class="com.example.service.StudentService">
<property name="studentDao" ref="studentDao"/>
</bean>
<!-- 寫(xiě)法2 -->
<!--<bean id="studentService" class="com.example.service.StudentService">
<property name="studentDao">
<ref bean="studentDao"/>
</property>
</bean>-->2. 注入基本數(shù)據(jù)類(lèi)型
<!-- 注入基本數(shù)據(jù)類(lèi)型 -->
<!-- 寫(xiě)法一 name:屬性名 value:屬性值 -->
<property name="name" value="程序員"/>
<!-- 寫(xiě)法二 name:屬性名 value:屬性值-->
<property name="count">
<value>10</value>
</property>3. 注入List集合
<!-- 注入List集合 -->
<!-- 簡(jiǎn)單的數(shù)據(jù)類(lèi)型List集合 name:屬性名 -->
<property name="students1" >
<list>
<value>上海</value>
<value>廣州</value>
</list>
</property>
<!-- 對(duì)象類(lèi)型的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>
<!-- 注入對(duì)象類(lèi)型map類(lèi)型 -->
<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對(duì)象
6. 注入Properties對(duì)象
<!-- 注入properties -->
<property name="properties">
<props>
<prop key="配置1">值1</prop>
<prop key="配置2">值2</prop>
</props>
</property>運(yùn)行測(cè)試方法測(cè)試一下

OK ,可以看到都是插入的了。
到此這篇關(guān)于詳解Spring DI依賴(lài)注入的方式和類(lèi)型的文章就介紹到這了,更多相關(guān)Spring DI依賴(lài)注入 內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JSON序列化Redis讀取出錯(cuò)問(wèn)題解決方案
這篇文章主要介紹了JSON序列化Redis讀取出錯(cuò)問(wèn)題解決方案,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Spring中異步注解@Async的使用、原理及使用時(shí)可能導(dǎo)致的問(wèn)題及解決方法
這篇文章主要介紹了Spring中異步注解@Async的使用、原理及使用時(shí)可能導(dǎo)致的問(wèn)題及解決方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
java解析dbf之通過(guò)javadbf包生成和讀取dbf文件
這篇文章主要介紹了java通過(guò)javadbf讀取和生成DBF文件的方法,大家參考使用吧2014-01-01
spring cloud gateway集成hystrix實(shí)戰(zhàn)篇
這篇文章主要介紹了spring cloud gateway集成hystrix實(shí)戰(zhàn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Ribbon單獨(dú)使用,配置自動(dòng)重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式
這篇文章主要介紹了Ribbon單獨(dú)使用,配置自動(dòng)重試,實(shí)現(xiàn)負(fù)載均衡和高可用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
Spring Data JPA進(jìn)行數(shù)據(jù)分頁(yè)與排序的方法
這篇文章主要介紹了Spring Data JPA進(jìn)行數(shù)據(jù)分頁(yè)與排序的方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-11-11
SpringBoot消息國(guó)際化配置實(shí)現(xiàn)過(guò)程解析
這篇文章主要介紹了SpringBoot消息國(guó)際化配置實(shí)現(xiàn)過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
springboot+redis實(shí)現(xiàn)簡(jiǎn)單的熱搜功能
這篇文章主要介紹了springboot+redis實(shí)現(xiàn)一個(gè)簡(jiǎn)單的熱搜功能,通過(guò)代碼介紹了過(guò)濾不雅文字的過(guò)濾器,代碼簡(jiǎn)單易懂,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-05-05

