Spring DI(依賴注入)的幾種方法
文章目錄
- Spring DI(依賴注入)的幾種方法
-
- DI概念
- 一、 set方法注入
-
- a. 建立StudentDao.java類
- b. 建立StudentService.java類
- c. 建立bean.xml檔案
- d. 建立測試類
- 二、 構造器注入
-
- a. 建立Student.java類
- b. 建立bean.xml檔案
-
- 1. 按照名字注入
- 2. 按照類型與索引注入
- c. 建立測試類
- 三、 工廠注入
-
- a. 建立工廠類
- b. 配置bean.xml檔案
-
- 1. 普通工廠
- 2. 靜态工廠
- c. 建立測試類
- d. 總結
- 四、 自動注入
-
- a. 建立UserDao.java類
- b. 建立UserService.java類
- c. 建立bean.xml檔案
-
- 1. byName注入
- 2. byType注入
- d. 建立測試類
- 五、 所有bean設定自動注入
DI概念
DI:Dependency Injection 依賴注入,在Spring架構負責建立Bean對象時,動态的将依賴對象注入到Bean元件。
一、 set方法注入
預設情況下,DI會自動調用Bean對象的無參構造器,然後通過對應的set方法注入值,是以一定要保證無參構造器、set方法存在。
當程式調用applicationContext.getBean("id值")的時候,Spring系統會先找到對應的類的無參構造器執行個體化一個對象,然後再調用其setXxx("")方法注入屬性值。
配置檔案中借助<property name="屬性名" ref="id"></property>實作set注入,如果該屬性是基本類型或者對應的包裝類型,可将ref更換為value,然後直接寫值,比如<property name="age" value="20"></property>。
a. 建立StudentDao.java類
package com.au.dao;
public class StudentDao {
public void addStudent() {
System.out.println("dao: addStudent()...");
}
}
b. 建立StudentService.java類
package com.au.service;
import com.au.dao.StudentDao;
public class StudentService {
// 需要set注入,建立setStudentDao方法
StudentDao studentDao;
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
public void addStudent() {
studentDao.addStudent();
}
}
c. 建立bean.xml檔案
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean配置 -->
<bean id="studentDaoId" class="com.au.dao.StudentDao"></bean>
<!-- 裡面用property标簽來實作set注入 -->
<bean id="studentServiceId" class="com.au.service.StudentService">
<property name="studentDao" ref="studentDaoId"></property>
</bean>
</beans>
d. 建立測試類
package com.au.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.au.service.StudentService;
public class Main {
@Test
public void test01() {
// Spring IOC,不用自己new對象,通過Spring來實作調用addStudent方法,底層使用了工廠模式+反射
String xmlPath = "com/au/test/bean.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(xmlPath);
StudentService service = (StudentService) ac.getBean("studentServiceId");
// 可以發現,并沒有new StudentDao對象,一樣可以調用addStudent()方法,說明注入成功
service.addStudent();
}
}
二、 構造器注入
a. 建立Student.java類
- 注意需要寫帶參構造器。
package DI_test;
public class Student {
private Integer id;
private String name;
public Student() {
}
public Student(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
@Override
public String toString() {
return "Student [id=" + id + ", name=" + name + "]";
}
}
b. 建立bean.xml檔案
- 按照名字注入:需要
标簽的
constructor-arg
值與類中屬性的名稱一緻。
name
- 按照類型與索引注入:下标從 開始,需要聲明對應的資料類型。
- 如果類中屬性不是基本類型,
标簽中用
constructor-arg
代替
ref
,與上述
value
注入類似。
set
1. 按照名字注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentId" class="DI_test.Student">
<constructor-arg name="id" value="10"></constructor-arg>
<constructor-arg name="name" value="張三"></constructor-arg>
</bean>
</beans>
2. 按照類型與索引注入
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="studentId" class="DI_test.Student">
<constructor-arg index="0" type="Integer" value="10"></constructor-arg>
<constructor-arg index="1" type="String" value="張三"></constructor-arg>
</bean>
</beans>
c. 建立測試類
package DI_test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
@Test
public void test01() {
String xmlPath = "DI_test/bean.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
Student student = (Student)context.getBean("studentId");
System.out.println(student);
}
}
三、 工廠注入
a. 建立工廠類
package DI_test;
public class StudentFactory {
/*
* 非靜态方法
*/
public Student getStudent() {
return new Student(1, "hzj");
}
/*
* 靜态方法
*/
public static Student getStudent_static() {
return new Student(2, "zhangsan");
}
}
b. 配置bean.xml檔案
1. 普通工廠
- 對于非靜态方法的注入方式,必須執行個體化工廠類
後才能調用工廠方法。
(factory-bean)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="factory" class="DI_test.StudentFactory"></bean>
<bean id="getStudent" factory-bean="factory" factory-method="getStudent"></bean>
</beans>
2. 靜态工廠
- 對于靜态方法的注入方式,無須建立工廠類執行個體的情況下就可以調用工廠類方法。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="getStudent" class="DI_test.StudentFactory" factory-method="getStudent_static"></bean>
</beans>
c. 建立測試類
package DI_test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
/*
* 測試靜态工廠
*/
@Test
public void test02() {
String xmlPath = "DI_test/bean.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
Student student = (Student) context.getBean("getStudent");
System.out.println(student);
}
/*
* 測試普通工廠
*/
@Test
public void test03() {
String xmlPath = "DI_test/bean.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
Student student = (Student) context.getBean("getStudent");
System.out.println(student);
}
}
d. 總結
- factory-bean:用于執行個體化工廠類。
- factory-method:用于調用工廠類方法。
四、 自動注入
自動注入:容器依照一些規則去裝配bean中的一個屬性。
自動注入有兩種形式,byName和byType。
a. 建立UserDao.java類
package autowire_test.dao;
public class UserDao {
public void addUser() {
System.out.println("添加成功!");
}
}
b. 建立UserService.java類
添加UserDao userDao為屬性,并添加setUserDao方法。
package autowire_test.service;
import autowire_test.dao.UserDao;
public class UserService {
UserDao userDao;
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void addUser() {
userDao.addUser();
}
}
c. 建立bean.xml檔案
1. byName注入
注入可以有兩個類型一樣的
byName
,根據類中屬性名來比對
bean
的
bean.xml
值。
id
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 因為屬性名叫userDao,是以會注入這個 -->
<bean id="userDao" class="autowire_test.dao.UserDao"></bean>
<!-- 因為屬性名叫userDao,是以不會注入這個 -->
<bean id="userDao1" class="autowire_test.dao.UserDao"></bean>
<bean id="userService" autowire="byName" class="autowire_test.service.UserService"></bean>
</beans>
2. byType注入
注入不能有兩個類型一樣的
byType
,否則會注入失敗。
bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userDao" class="autowire_test.dao.UserDao"></bean>
<!-- 不能有兩個一樣類型的bean -->
<!-- <bean id="userDao1" class="autowire_test.dao.UserDao"></bean> -->
<bean id="userService" autowire="byName" class="autowire_test.service.UserService"></bean>
</beans>
d. 建立測試類
package autowire_test.main;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import autowire_test.service.UserService;
public class Main {
@Test
public void test01() {
String xmlPath = "autowire_test/main/bean.xml";
ApplicationContext context = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) context.getBean("userService");
userService.addUser();
}
}
五、 所有bean設定自動注入
在beans标簽中将屬性default-autowire="byName"或"byType"即可。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"
default-autowire="byType">
<!-- ^ 這設定 -->
</beans>