一,什么是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()方法运行,输出结果如图所示: