Spring:IoC控制反转和Bean容器

通过一个实例来回顾。

首先是接口调用的实例,这个跟题目不直接相关,纯粹是回味。

定义接口类:

package com.imooc.ioc.interfaces;

public interface OneInterface {
	
	public String say(String arg);
	
}

定义实例类,实例化接口:

package com.imooc.ioc.interfaces;

public class OneInterfaceImpl implements OneInterface {
	
	@Override
	public String say(String arg) {
		//System.out.println("ServiceImpl say: " + arg);
		return "ServiceImpl say: " + arg;
	}

}

下面就是控制反转和Bean的简单例子,控制反转就是讲对象的创建交给Bean容器,而Bean就是其中的对象,利用控制反转的思想,我们就不需要自己创建对象了,只需要在使用的时候像Bean容器请求在容器初始化时已经创建好的对象即可。

接着上面两个类,我们先写个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" >

    <!-- id为类的标识,在测试类中调用使用,class为相应的类 -->  
	<bean id="oneInterface" class="com.imooc.ioc.interfaces.OneInterfaceImpl"></bean>
	
 </beans>

只有中间一行是我们的内容,其他都是版本什么的内容。

id为该xml文件中对象的标识,class就是相应的类。

现在对象已经加入xml文件了。

我们用一个test类向Bean容器请求该对象:

package com.imooc.test.ioc.interfaces;
//单元测试
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.BlockJUnit4ClassRunner;
//import org.springframework.test.context.ContextConfiguration;
//import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.imooc.ioc.interfaces.OneInterface;
import com.imooc.test.base.UnitTestBase;
//每个测试类都要加上下面的注解
@RunWith(BlockJUnit4ClassRunner.class)
//UnitTestBase类,完成对spring配置文件的加载,销毁,所有的单元测试类都继承自它,通过它的getBean方法获得对象
public class TestOneInterface extends UnitTestBase {
	//对相应的xml文件的添加
	public TestOneInterface() {
		super("classpath*:spring-ioc.xml");
	}
	//@Test是所有单元测试方法都要加上的注解
	@Test
	public void testSay() {
		//定义一个接口为从getBean获得的oneInterface对象
		OneInterface oneInterface = super.getBean("oneInterface");
		oneInterface.say("This is a test.");
		//调用该对象的方法
		System.out.println(oneInterface.say("This is a test."));
	}
}

从下往上看,getBean就是请求该对象的操作了,所以根据上面的内容,我们调用这个testSay方法可以输出:

7月 31, 2018 10:38:29 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e9e725a: startup date [Tue Jul 31 22:38:29 CST 2018]; root of context hierarchy
7月 31, 2018 10:38:30 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from URL [file:/E:/eclipse/workspace/Spring/classes/spring-ioc.xml]
ServiceImpl say: This is a test.
7月 31, 2018 10:38:30 下午 org.springframework.context.support.AbstractApplicationContext doClose
信息: Closing org.springframework.context.support.ClassPathXmlApplicationContext@1e9e725a: startup date [Tue Jul 31 22:38:29 CST 2018]; root of context hierarchy

可以从结果的第五行看到,我们没有自己new对象,就创建了一个对象,并调用了方法。

那么是如何做到的呢,其实关键就在于测试类的父类:UnitTestBase

我们打开父类看一下:

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

}

可以看到父类在@before中就把相应的xml文件上下文添加了,

之后父类还写好了getBean的方法,可以看到能通过id来创建相应的对象。(这块理解还不是很深入,大致意思)

所以在测试类中我们可以根据xml中的id来请求相应的对象。

这样我们无需自己管理对象,无需自己创建对象,我们只要请求就得到了对象。

over!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值