Spring DI 依賴注入有幾種方式?
Spring DI 依賴注入有幾種方式?
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-qzqhGVem-1600425404270)(https://imgkr.cn-bj.ufileos.com/50416f44-5b7e-43bb-a0c4-ee71be577c04.jpg)]
Spring 例項化 bean 的方式
- Set注入
- 構造器注入
- 靜態工廠注入
- 例項化工廠注入
案例實操
Set注入
xml配置(同時spring也提供了對於基本資料型別的set注入方式)
<?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="com.xxx.demo.UserDao"></bean> <!-- setter注入 --> <bean id="userService" class="com.xxx.demo.UserService"> <!--ref是對於外部bean物件引用,與被引用的bean物件的id保持一致--> <property name="userDao" ref="userDao"></property> </bean> </beans>
UserDao.java
public class UserDao {
public String userLogin() {
return "我是UserDao中的userLogin()的方法";
}
}
UserService.java
public class UserService { //一定要提供屬性的setter方法 private UserDao userDao; public void userlogin() { String res=userDao.userLogin(); System.out.println(res); } public void setUserDao(UserDao userDao) { this.userDao = userDao; } }
App.java
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class App { public static void main(String[] args) { ApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring-config.xml"); UserService userService=applicationContext.getBean("userService", UserService.class); userService.userlogin(); } }
構造器注入
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 id="userDao" class="com.xxx.demo.UserDao"></bean>
<!-- 構造器注入 -->
<bean id="userServiceV2" class="com.xxx.demo.UserServiceV2">
<constructor-arg index="0" ref="userDao"></constructor-arg>
<constructor-arg index="1" value="印度三哥"></constructor-arg>
</bean>
</beans>
構造器注入有三種形式:
index屬性為引數順序,如果只有一個引數index可以不設定。
name屬性根據構造器中屬性的名字。
type屬性,是根據構造器中屬性的型別來匹配的。如果相同型別屬性不唯一,注入的屬性按照順序注入進來。
UserServiceV2.java類提供建構函式
/**
* 實現構造器注入
* @author Best Liu
*
*/
public class UserServiceV2 {
private UserDao userDao;
private String name;
public void userlogin() {
String res=userDao.userLogin();
System.out.println(res);
System.out.println(name);
}
public UserServiceV2(UserDao userDao,String name) {
super();
this.userDao = userDao;
this.name = name;
}
}
靜態工廠注入
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 id="userDao01" class="com.xxx.demo.StaticFactory" factory-method="createuserDao"></bean>
<bean id="userService01" class="com.xxx.demo.UserService">
<property name="userDao" ref="userDao01"></property>
</bean>
</beans>
StaticFactory.java
public class StaticFactory {
public static UserDao createuserDao(){
return new UserDao();
}
}
UserService.java
public class UserService {
private UserDao userDao;
public void userlogin() {
String res=userDao.userLogin();
System.out.println(res);
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
}
tips:靜態工廠注入就是IoC靜態工廠和DI的setter注入,將需要注入的屬性物件利用靜態工廠創建出來.
2.4 例項化工廠
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 id="instanceFactory" class="com.xxx.demo.InstanceFactory"></bean>
<bean id="userDao3" factory-bean="instanceFactory" factory-method="createUserDao"></bean>
<bean id="userService02" class="com.xxx.demo.UserService">
<property name="userDao" ref="userDao3"></property>
</bean>
</beans>
InstanceFactory.java
public class InstanceFactory {
public UserDao createUserDao(){
return new UserDao();
}
}
tips:重點掌握set,構造器注入,工廠方式瞭解即可,實際開發中基本使用set方式注入bean。
擴充套件
迴圈依賴的問題的產生
Bean通過構造器注入,之間彼此相互依賴對方導致bean無法例項化。
注入的選擇:開發專案中set方式注入首選
使用構造注入可以在構建物件的同時一併完成依賴關係的建立,物件一建立則所有的一切也就準備好了,但如果要建立的物件關係很多,使用構造注入會在構建函式上留下一長串的引數,且不易記憶,這時使用Set注入會是個不錯的選擇。
使用Set注入可以有明確的名稱,可以瞭解注入的物件會是什麼,像setxxx()這樣的名稱比記憶Constructor上某個引數的位置代表某個物件更好。
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 id="goodsService" class="com.xxx.demo.GoodsService">
<!-- <constructor-arg index="0" ref="userService"></constructor-arg> -->
<property name="userService" ref="userService"></property>
</bean>
<bean id="userService" class="com.xxx.demo.UserService">
<!-- <constructor-arg index="0" ref="goodsService"></constructor-arg> -->
<property name="goodsService" ref="goodsService"></property>
</bean>
</beans>
GoodsService.java
public class GoodsService {
private UserService userService;
/*public GoodsService(UserService userService) {
super();
this.userService = userService;
}*/
public void setUserService(UserService userService) {
this.userService = userService;
}
}
UserService.java
public class UserService {
private GoodsService goodsService;
/* public UserService(GoodsService goodsService) {
super();
this.goodsService = goodsService;
}
*/
public void setGoodsService(GoodsService goodsService) {
this.goodsService = goodsService;
}
}
class UserService {
private GoodsService goodsService;
/* public UserService(GoodsService goodsService) {
super();
this.goodsService = goodsService;
}
*/
public void setGoodsService(GoodsService goodsService) {
this.goodsService = goodsService;
}
}