一,什麼是Spring注入
Spring注入是指在啟動Spring容器加載bean配置的時候,完成對變量的指派行為。
二,Spring注入方式
Spring注入方式有兩種,第一種是設值注入(通過類提供的set()方法注值),第二種是構造注入(通過類提供的構造方法注值)。
三,工程搭建
由于本次是進行簡單的測試,是以隻用普通java項目進行測試,讀者為了友善導入jar包可自行建立maven工程。
項目目錄結構
InjectionDAO
package com.injection.dao;
public interface InjectionDAO {
/**
* 通路資料庫的操作
*
* @param str
*/
public void save(String str);
}
InjectionDAOImpl
package com.injection.dao;
public class InjectionDAOImpl implements InjectionDAO {
@Override
public void save(String str) {
System.out.println(str + "被存儲到資料庫...");
}
}
InjectionService
package com.injection.service;
public interface InjectionService {
/**
* 業務操作
*
* @param str
*/
public void save(String str);
}
InjectionServiceImpl
package com.injection.service;
import com.injection.dao.InjectionDAO;
public class InjectionServiceImpl implements InjectionService {
private InjectionDAO injectionDAO;
/**
* 構造方法注入
*
* @param injectionDAO
*/
public InjectionServiceImpl(InjectionDAO injectionDAO) {
super();
this.injectionDAO = injectionDAO;
}
/**
* setter() 方法注入
*
* @param injectionDAO
*/
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
}
@Override
public void save(String str) {
System.out.println("Service對" + str + "進行業務處理...");
str = str + ":" + str.hashCode();
injectionDAO.save(str);
}
}
UnitTestBase
package com.injection.test;
import org.junit.After;
import org.junit.Before;
import org.springframework.beans.BeansException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.util.StringUtils;
public class UnitTestBase {
private ClassPathXmlApplicationContext context;
private String springXmlpath;// 就是配置spring的bean容器的路徑字元串,通過構造器獲得
public UnitTestBase() {
}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
/**
* classpath*是目前jar包目錄下的所有的jar包下進行的操作, 比如掃描等,classpath隻是目前單獨一個jar包裡的操作。比如在掃描器中,
* classpath隻掃描目前包裡的class,classpath*則掃描的是目前包目錄下所有的包裡的class.
*/
springXmlpath = "classpath*:spring-*.xml";
}
try {
/**
* str.split(String regex)作用:根據正規表達式regex,将字元串str, 分割成字元串數組。"[,\\s]+"
* 是一個正規表達式,\\s表示各種空白符,+表示比對多個。
* StringUtils是org.apache.commons.lang下的一個用于操作Java.lang.String的工具類,
* 使用可能需要手工導入commons-lang-xx.jar 把SpringXmlpath路徑拆分開來,
* 因為springXmlpath路徑可能是多個路徑的拼接,拆分過之後每個路徑下的xml都會被掃描識别
*/
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();// 通過掃描xml檔案擷取并啟動容器
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
/**
* T 這是泛型,在你不确定使用什麼類型參數的時候,泛型可以代表任意一種類型參數,比較靈活友善
*/
return (T) context.getBean(beanId);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
protected <T extends Object> T getBean(Class<T> clazz) {
try {
return context.getBean(clazz);
} catch (BeansException e) {
e.printStackTrace();
return null;
}
}
}
InjectionTest
package com.injection.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.injection.service.InjectionService;
@RunWith(BlockJUnit4ClassRunner.class)
public class InjectionTest extends UnitTestBase {
public InjectionTest() {
super("classpath:spring-injection.xml");
}
/**
* setter()方法注入測試
*/
@Test
public void testSetter() {
InjectionService service = super.getBean("injectionService");
service.save("data");
}
/**
* constructor()方法注入測試
*/
@Test
public void testConstructor() {
InjectionService service = super.getBean("injectionService");
service.save("data");
}
}
spring-injection.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="injectionService" class="com.injection.service.InjectionServiceImpl">
<property name="injectionDAO" ref="injectionDAO"></property>
</bean>
<!-- <bean id="injectionService" class="com.injection.service.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean> -->
<bean id="injectionDAO" class="com.injection.dao.InjectionDAOImpl"></bean>
</beans>
四,代碼運作解釋
測試setter()方法注入:
在這之前一需要確定InjectionServiceImpl中編寫了對InjectionDAO對象的set設值方法,二需要確定spring-injection.xml中injectionService對injectionDAO的配置是
<property name="injectionDAO" ref="injectionDAO"></property>這種方式。
把 <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean>這一段代碼注釋掉
在InjectionTest類中右擊testSetter()方法運作,輸出結果如圖所示:
測試構造方法注入:
在這之前一需要確定InjectionServiceImpl中編寫構造方法對InjectionDAO對象設值,二需要確定spring-injection.xml中injectionService對injectionDAO的配置是
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>這種方式。
把 <bean id="injectionService" class="com.injection.service.InjectionServiceImpl">
<property name="injectionDAO" ref="injectionDAO"></property>
</bean>這一段代碼注釋掉
在InjectionTest類中右擊testConstructor()方法運作,輸出結果如圖所示: