控制反转,就是在启动Bean容器的时候,Bean容器会加载xml文件,加载里面对于bean的配置,来创建对象,来初始化对象。
而注入就是说,在初始化对象的过程中(加载bean配置的同时),完成对对象的成员变量赋值。
这节就是对注入方式的实践,注入方式分为设值注入和构造注入两种。
首先是设值注入:
建立两个接口和两个实例,其中一个实例是另一个实例的成员变量
//接口1
package com.imooc.ioc.injection.dao;
public interface InjectionDAO {
public void save(String arg);
}
//实例1
package com.imooc.ioc.injection.dao;
public class InjectionDAOImpl implements InjectionDAO {
public void save(String arg) {
//模拟数据库保存操作
System.out.println("保存数据:" + arg);
}
}
//接口2
package com.imooc.ioc.injection.service;
public interface InjectionService {
public void save(String arg);
}
//实例2
package com.imooc.ioc.injection.service;
import com.imooc.ioc.injection.dao.InjectionDAO;
public class InjectionServiceImpl implements InjectionService {
private InjectionDAO injectionDAO;
/*//构造器注入
public InjectionServiceImpl(InjectionDAO injectionDAO1) {
this.injectionDAO = injectionDAO1;
}*/
//设值注入,通过set方法来实现
public void setInjectionDAO(InjectionDAO injectionDAO) {
this.injectionDAO = injectionDAO;
}
public void save(String arg) {
//模拟业务操作
System.out.println("Service接收参数:" + arg);
arg = arg + ":" + this.hashCode();
injectionDAO.save(arg);
}
}
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.imooc.ioc.injection.service.InjectionServiceImpl">
<!--设值注入在xml中的操作就是添加一个属性propoty-->
<!--左侧的name代表业务实例中的set方法参数-->
<!--右侧的ref是下面的DAO实例的对象ID-->
<property name="injectionDAO" ref="injectionDAO"></property>
</bean>
<!-- <bean id="injectionService" class="com.imooc.ioc.injection.service.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean> -->
<bean id="injectionDAO" class="com.imooc.ioc.injection.dao.InjectionDAOImpl"></bean>
</beans>
添加测试文件
package com.imooc.test.ioc.interfaces;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.imooc.ioc.injection.service.InjectionService;
import com.imooc.test.base.UnitTestBase;
@RunWith(BlockJUnit4ClassRunner.class)
public class TestInjection extends UnitTestBase {
//导入相应的xml配置
public TestInjection() {
super("classpath:spring-injection.xml");
}
@Test
public void testSetter() {
//请求相应的业务对象
InjectionService service = super.getBean("injectionService");
//业务对象调用成员变量的方法
service.save("这是要保存的数据");
}
@Test
public void testCons() {
InjectionService service = super.getBean("injectionService");
service.save("这是要保存的数据");
}
}
运行testsetter方法
8月 01, 2018 10:23:33 上午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@146044d7: startup date [Wed Aug 01 10:23:33 CST 2018]; root of context hierarchy
8月 01, 2018 10:23:34 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [spring-injection.xml]
Service接收参数:这是要保存的数据
保存数据:这是要保存的数据:1292738535
8月 01, 2018 10:23:34 上午 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@146044d7: startup date [Wed Aug 01 10:23:33 CST 2018]; root of context hierarchy
可以看到在业务实例中,虽然有个set方法,但是这个方法并没有被显式地调用,那么是如何完成赋值配置的呢?
就是通过xml文件中的propoty完成的赋值效果。
而构造注入方式类似,上面已经提供了对应的代码和方法。