`

【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)

阅读更多

目录
【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八)
【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主动查找和控制反转(九)
【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十)
【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)已更新

 

上上篇博文【SSH进阶之路】一步步重构容器实现Spring框架——从一个简单的容器开始(八),我们为了去掉接

口对具体实现的依赖关系,封装了一个特别简陋的容器。

上篇博文【SSH进阶之路】一步步重构容器实现Spring框架——解决容器对组件的“侵入式”管理的两种方案--主

动查找和控制反转(九),我们利用控制反转,去掉了组件对容器的依赖。

 

简单配置,反射

 

上篇博文容器初始化时,使用new的方式来实力化对象,这篇博文我们利用配置文件+反射实力化对象,进一步封

装降低容器和组件的耦合度。下面我们先看一下配置文件。

 

<?xml version="1.0" encoding="UTF-8"?>
<beans>

  <bean id="dao" class="com.tgb.container.dao.impl.Dao4MySqlImpl" />
  
  <bean id="service" class="com.tgb.container.service.impl.ServiceImpl" />
	
</beans>

看到上面的配置文件,除了命名空间没有,和Spring的配置文件已经很像了,下面我们就使用dom4j或jdom来读取

配置文件,并将配置文件中配置类利用反射实例化。本实例我们使用的jdom,大家也可以使用dom4j试一下。下面我

们看一下读取配置文件的代码:

 

public interface BeanFactory {

	Object getBean(String id);
}
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import com.tgb.container.dao.Dao;
import com.tgb.container.service.Service;

/**
 * 从类路径加载配置文件
 * 
 * @author liang
 * 
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

	// 用于存放Bean
	private Map<String, Object> beans = new HashMap<String, Object>();

	public ClassPathXmlApplicationContext(String fileName) {

		this.readXML(fileName);

	}

	// 解析xml文件,通过反射将配置的beasn放到container中,并实现依赖注入
	private void readXML(String fileName) {
		// 创建SAXBuilder对象
		SAXBuilder saxBuilder = new SAXBuilder();
		// 读取资源,获得document对象
		Document doc;
		try {
			doc = saxBuilder.build(this.getClass().getClassLoader().getResourceAsStream(fileName));

			// 获取根元素
			Element rootEle = doc.getRootElement();
			// 从根元素获得所有的子元素,建立元素集合
			List listBean = XPath.selectNodes(rootEle, "/beans/bean");

			// 遍历根元素的子元素集合,扫描配置文件中的bean
			for (int i = 0; i < listBean.size(); i++) {
				Element bean = (Element) listBean.get(i);
				// 获取id属性值
				String id = bean.getAttributeValue("id");
				// 获取class属性值
				String clazz = bean.getAttributeValue("class");
				// 反射,实例化
				Object o = Class.forName(clazz).newInstance();
				beans.put(id, o);
			}

			// 依赖管理,这里还不灵活,但是原理是一样的
			Service service = (Service) beans.get("service");
			Dao dao = (Dao) beans.get("dao");
			// 依赖注入,Service实现依赖dao的实现
			service.setDao(dao);

		} catch (Exception e) {

			e.printStackTrace();
		}
	}

	/**
	 * 查找组件
	 * 
	 * @param id
	 * @return
	 */
	@Override
	public Object getBean(String id) {
		return beans.get(id);
	}
}


看到上面的代码,我们发现读取配置文件的方法中包含了反射,代码的可读性太差,并且对面向对象的封装不够彻

 

底,下面我们将bean的实例化以及依赖注入进行进一步的封装。

 

 

封装bean的实例化

 

为了做进一步的封装,我们将配置文件的属性封装成一个javabean,为了存放我们的属性值。如下所示:

 

public class BeanDefinition {

	private String id;
	private String className;

	
	public BeanDefinition(String id, String className) {
		this.id = id;
		this.className = className;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getClassName() {
		return className;
	}

	public void setClassName(String className) {
		this.className = className;
	}

}


现在我们就可以把bean的实例化做进一步的封装了。

 

 

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.input.SAXBuilder;
import org.jdom.xpath.XPath;

import com.tgb.container.dao.Dao;
import com.tgb.container.service.Service;

/**
 * 容器
 * 
 * @author liang
 * 
 */
public class ClassPathXmlApplicationContext implements BeanFactory {

	// 用于存放Bean
	private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	// 用于存放Bean的实例
	private Map<String, Object> sigletons =new HashMap<String, Object>();
	
	
	public ClassPathXmlApplicationContext(String fileName) {

		this.readXML(fileName);
		
		this.instanceBeans();
		
		this.injectObject();
	}

	/**
	 * 依赖注入,为bean对象的属性注入值
	 * 这里还不灵活,但是原理是一样的
	 */
	private void injectObject() {
		Service service = (Service) this.sigletons.get("service");
		Dao dao = (Dao) this.sigletons.get("dao");
		//依赖注入,Service实现依赖dao的实现
		service.setDao(dao);
	}

	/**
	 * 完成bean的实例化
	 */
	private void instanceBeans() {
		for(BeanDefinition beanDefinition : beanDefines){
			try {
				if(beanDefinition.getClassName() != null && !"".equals(beanDefinition.getClassName().trim())){
					sigletons.put(beanDefinition.getId(),Class.forName(beanDefinition.getClassName()).newInstance() );
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 读取xml配置文件
	 */
	private void readXML(String fileName) {
		// 创建SAXBuilder对象
		SAXBuilder saxBuilder = new SAXBuilder();

		try {
			// 读取资源,获得document对象
			Document doc = saxBuilder.build(this.getClass().getClassLoader()
					.getResourceAsStream(fileName));
			// 获取根元素
			Element rootEle = doc.getRootElement();
			// 从根元素获得所有的子元素,建立元素集合
			List listBean = XPath.selectNodes(rootEle, "/beans/bean");

			// 遍历根元素的子元素集合,扫描配置文件中的bean
			for (int i = 0; i < listBean.size(); i++) {
				Element bean = (Element) listBean.get(i);
				// 获取id属性值
				String id = bean.getAttributeValue("id");
				// 获取class属性值
				String clazz = bean.getAttributeValue("class");
				
				BeanDefinition beanDefine = new BeanDefinition(id,clazz);
				// 将javabean添加到集合中
				beanDefines.add(beanDefine);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}


	/**
	 * 获取bean实例
	 */
	@Override
	public Object getBean(String beanName) {
		return this.sigletons.get(beanName);
	}

}

 

我们知道容器不仅负责创建对象,而且可以管理对象的依赖关系,管理对象的生命周期等等。我们仅实现了容器

灵活创建对象的部分,依赖注入部分是由我们手动注入的。 对象的依赖关系还不灵活,但是我们已经能够看到IoC的

影子了,只是形似,还没有达到神似的目标。

下篇博文【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一),马

上送上。

 

 

源码下载

 

分享到:
评论

相关推荐

    Spring框架的简单实现

    我们从一个简单的容器开始,一步步的...【SSH进阶之路】一步步重构容器实现Spring框架——配置文件+反射实现IoC容器(十) 【SSH进阶之路】一步步重构容器实现Spring框架——彻底封装,实现简单灵活的Spring框架(十一)

    SpringIoC的简单实现

    我们从一个简单的容器开始,一步步的重构,最后实现一个基本的Spring框架的雏形,为了帮助我们更加深入的理解Spring的IoC的原理...【SSH进阶之路】一步步重构容器实现Spring的IoC——工厂+反射+配置文件实现IoC容器(十)

    基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)

    基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)...

    Android进阶——框架打造之IOC框架

    Android进阶——框架打造之IOC框架 实现通过Id找到控件的功能 实现通过Id找到Color、String资源 实现绑定view的点击事件、长按事件 实现绑定SetContentView 实现绑定网络的检测功能

    spring Ioc容器配置

    spring Ioc容器配置 IOC容器数据源配置 &lt;!-- 配置数据源 --&gt; destroy-method="close"&gt; &lt;value&gt;org.gjt.mm.mysql.Driver &lt;value&gt;jdbc:mysql://localhost:3306/demo &lt;value&gt;root ...

    手写spring框架ioc+aop+mvc

    手写spring框架ioc+aop+mvc

    自己动手做框架——ORM,MVC,IOC框架

    自己动手做框架——ORM,MVC,IOC框架及整合视频教程 源码

    Java仿Spring框架IOC控制反转利用反射简单实现(源码)

    Java仿Spring框架IOC控制反转利用反射简单实现(源码) Java仿Spring框架IOC控制反转利用反射简单实现(源码)

    springIOC手写框架分析

    springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC手写框架分析springIOC...

    SSM框架——(SpringMVC+Spring+MyBatis+Maven多模块)整合

    SpringMVC+Spring+MyBatisMaven多模块项目地址:SpringMVC:1...视图负责将结果显示到客户端Spring:1.Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器架构,IOC容器包含并管理应用对象的配置和生命周期,你

    模拟Spring的IoC容器实现注解自动装配

    自己实现的简易的模拟Spring的IoC容器,实现注解自动装配

    一步步实现Spring框架(一)项目搭建

    自己来实现Spring框架原理,也好加强对Java的理解 博客地址:http://my.oschina.net/u/865381/blog/225649

    Spring5 框架 ---- IOC容器 ---- 代码

    Spring5 框架 ---- IOC容器 ---- 代码 Spring5 框架 ---- IOC容器 ---- 代码 Spring5 框架 ---- IOC容器 ---- 代码 Spring5 框架 ---- IOC容器 ---- 代码 Spring5 框架 ---- IOC容器 ---- 代码 Spring5 框架 ---- ...

    编程语言+JAVAspring+IoC容器+依赖注入

    编程语言+JAVAspring+IoC容器+依赖注入**:这是一...它介绍了JAVAspring的IoC容器的概念、原理和作用,以及如何使用JAVAspring的IoC容器来实现依赖注入,包括设值注入和构造注入的方式,以及一些配置文件和注解的用法。

    Spring的IoC容器(《Spring揭秘》的精选版)

    迷你书是《Spring揭秘》的精选版,节选了原书中介绍Spring IoC容器的6个章节。《Spring揭秘》以幽默生动的语言、辅以有趣的故事和典故,循循善诱地阐述了Spring框架的方方面面。针对Spring框架的主要功能以及开发者...

    模拟实现Spring的IOC

    2、本工程,模拟实现Spring的IOC,将xml中配置的Bean读入到Spring容器中,并在测试用例中调用Spring容器中的bean。 3、开发环境eclipse,jdk1.6。使用第三方jar包有:jdom.jar(用于解析xml文件),junit-4.4.jar...

    Spring总结——Spring容器、Spring中的IoC

    文章目录Spring总结Spring容器控制反转(IoC)基于XML的IoC Spring总结 Spring容器 什么是Spring容器 从概念上讲:Spring 容器是 Spring框架的核心,是用来管理对象的。容器将创建对象,把它们连接在一起,配置它们...

    spring ioc+mvc代码

    自己实现的spring ioc+mvc框架,具体流程参考的spring,可以加深对spring源码流程的理解

    springIoc实现原理

    spring ioc指的是控制反转,IOC容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。交由Spring容器统一进行管理,从而实现松耦合

    Spring源代码解析(一):IOC容器.doc

    Spring源代码解析(一):IOC容器.doc

Global site tag (gtag.js) - Google Analytics