IOC容器:
按照我的理解为:我们需要什么都交给容器来实现 比如原先我们需要得到就要 new 一个实例,有了容器需要实例就让容器创建,需要变量,属性就让容器注入。
简单的接口实例:
package com.interface1;
public interface OneInterface {
public void say(String arg);
}
++++++++++++++++++++++++++++++++
package com.interface1;
/*
* OneInterface实现类
*/
public class OneInterfaceImpl implements OneInterface {
public void say(String arg) {
System.out.println("ServiceImpl say: " + arg);
}
}
++++++++++++++++++++++++++
package com.interface1;
public class Main {
public static void main(String[] args){
/*
* 简单的面向接口编程:把接口实现类赋值给接口的声明:oif
*/
OneInterface oif=new OneInterfaceImpl();
oif.say("Hello Spring");
}
}
++++++++++++++++++++++++++
使用IOC容器来实现(也是上面的接口和接口实现类)
需要junit相关jar包以及spring相关jar包。。。。。。。
工具类:
package com.imooc.test.base;
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;
public UnitTestBase() {}
public UnitTestBase(String springXmlpath) {
this.springXmlpath = springXmlpath;
}
@Before
public void before() {
if (StringUtils.isEmpty(springXmlpath)) {
springXmlpath = "classpath*:spring-*.xml";
}
try {
context = new ClassPathXmlApplicationContext(springXmlpath.split("[,\\s]+"));
context.start();
} catch (BeansException e) {
e.printStackTrace();
}
}
@After
public void after() {
context.destroy();
}
@SuppressWarnings("unchecked")
protected <T extends Object> T getBean(String beanId) {
try {
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;
}
}
}
package com.interface1;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.imooc.test.base.UnitTestBase;
@RunWith(BlockJUnit4ClassRunner.class)
public class MainTestJunit extends UnitTestBase{
public MainTestJunit() {
super("classpath*:spring-ioc.xml");
}
@Test
public void testSay() {
OneInterface oneInterface = super.getBean("oneInterface");
oneInterface.say("Hello Boy");
}
}
Spring配置文件:(spring-ioc.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="oneInterface" class="com.interface1.OneInterfaceImpl"></bean>
</beans>
如果像上面的操作似乎比一般的方法更加麻烦
当多个接口有多个对象的时候 就需要一个一个的new了 就很麻烦:
定义两个接口 两个接口实现类
其中InjectionDao为InjectionServiceImpl 的属性
package com.inner;
public interface InjectionDao {
public void save(String arg);
}
package com.inner;
public class InjectionDaoImpl implements InjectionDao {
@Override
public void save(String arg) {
// TODO Auto-generated method stub
System.out.println("模拟数据库操作:保存数据"+arg);
}
}
package com.inner;
public interface InjectionService {
public void save(String arg);
}
如何给InjectionServiceImpl注入值 :两种方法
1:设置注入: propety name 为变量名 要为这个变量设置set方法
2:构造器注入: 需要显式的构造器 构造器的参数名和name后的一致
package com.inner;
public class InjectionServiceImpl implements InjectionService{
private InjectionDao injectionDAO;
//设值注入
public void setInjectionDAO(InjectionDao injectionDAO) {
this.injectionDAO = injectionDAO;
}
//构造注入:
public InjectionServiceImpl(InjectionDao injectionDAO){
this.injectionDAO = injectionDAO;
}
@Override
public void save(String arg) {
System.out.println("模拟业务操作:保存数据"+arg);
arg=arg+":"+arg.hashCode();
injectionDAO.save(arg);
}
}
+++++++++++++++++++++++++++++++
两种方式在配置文件中得配置:
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="injectionService1" class="com.inner.InjectionServiceImpl">
<property name="injectionDAO" ref="injectionDAO"></property>
</bean>
-->
<bean id="injectionService2" class="com.inner.InjectionServiceImpl">
<constructor-arg name="injectionDAO" ref="injectionDAO"></constructor-arg>
</bean>
<bean id="injectionDAO" class="com.inner.InjectionDaoImpl"></bean>
</beans>
测试类:
package com.inner;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
import com.imooc.test.base.UnitTestBase;
@RunWith(BlockJUnit4ClassRunner.class)
public class TestInjection extends UnitTestBase{
public TestInjection() {
super("classpath*:spring-injection.xml");
}
// @Test
// //设值植入
// public void testSetter() {
// InjectionService service = super.getBean("injectionService1");
// service.save("这是要保存的数据");
// }
//构造植入:
@Test
public void testConstor(){
InjectionService service = super.getBean("injectionService2");
service.save("这是要保存的数据");
}
}
总结:
其中 id为我理解的为该class=“”中类的实例 保存在IOC中 而
name=”injectionDAO” ref=”injectionDAO”>中得name的值为id的属性名 ref的值为<bean id="injectionDAO" class="com.inner.InjectionDaoImpl"></bean>
的id值
在xml文件中的类都是实现类 而在InjectionServiceImpl 的实现类中都是接口属性 接口属性使用的该接口实现类来实例化的
问题:
不懂public TestInjection() {
super("classpath*:spring-injection.xml");
}
中的super的classpath加星号和不加星号的区别