1. 程式人生 > 實用技巧 >Spring DI 依賴注入有幾種方式?

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;
}
}