`
xiaoye4188
  • 浏览: 30597 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

模拟Spring IOC

阅读更多

本模拟实现的功能:将如下xml文件中的bean加载进spring容器,同时将studentDao注入studentService中,最后通过getBean()获取bean


<?xml version="1.0" encoding="UTF-8"?>
<beans>
	<bean id="studentDao" class="com.zju.test.StudentDao"></bean>
	
	<bean id="studentService" class="com.zju.test.StudentService" >
		<property name="studentDao" ref="studentDao"/>
	</bean>
</beans>


一、数据结构的定义:

Spring中用BeanDefinition数据结构封装数据

BeanDefinition类:


package com.zju.xiaoye.bean;

import java.util.ArrayList;
import java.util.List;

/**
 * BeanDefinition 的定义类
 * 
 * @author xiaoye
 * 
 */
public class BeanDefinition {
	private String id;   //bean id
	private String className; //bean className
	private List<PropertyDefinition> properties = new ArrayList<PropertyDefinition>();  //定义bean中property子节点

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

	public BeanDefinition() {
	}

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

	public List<PropertyDefinition> getProperties() {
		return properties;
	}

	public void setProperties(List<PropertyDefinition> properties) {
		this.properties = properties;
	}

}


 而PropertyDefinition定义如下:


package com.zju.xiaoye.bean;

public class PropertyDefinition {
	private String name;  //name属性
	private String ref;  //ref属性

	public PropertyDefinition(String name, String ref) {
		this.name = name;
		this.ref = ref;
	}

	public PropertyDefinition() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getRef() {
		return ref;
	}

	public void setRef(String ref) {
		this.ref = ref;
	}

}



二、模拟容器的实现

模拟容器类MockSpringXmlApplicationContext主要的结构如下:

package com.zju.xiaoye.context;

import ......

public class MockSpringXmlApplicationContext {
	//BeanDefinition类型的List
	private List<BeanDefinition> beanDefines = new ArrayList<BeanDefinition>();
	
	//容器的主要数据结构beanDefinitionMap
	private Map<String, Object> beanDefinitionMap = new HashMap<String, Object>(); 
	
	/**
	 * MockSpringXmlApplicationContext构造函数
	 * 执行读取xml文件readXml(fileName);
	 * 初始化Beans方法initBeas();
	 * 实现依赖注入inject();
	 * @param fileName
	 */
	public MockSpringXmlApplicationContext(String fileName){
		this.readXml(fileName);
		this.initBeans();
		this.inject();
	}
	
	/**
	 * 读取xml文件信息进行解析
	 * 并将bean节点加入beanDefines中
	 * @param fileName
	 */
	private void readXml(String fileName){
		.......
	}
	
	/**
	 * 遍历beanDefines将bean加入map中
	 */
	private void initBeans(){
		......
	}
	
	/**
	 * 根据set方法实现依赖注入
	 * 遍历beanDefines集合,对每个beanDefinition,实现property节点的注入功能
	 */
	private void inject(){
		......
	}
	
	/**
	 * 根据id从容器中获取bean
	 * @param id
	 * @return
	 */
	public Object getBean(String id){
		return beanDefinitionMap.get(id);
	}
	
}

 下面介绍主要的方法实现

  1)readXml(String fileName):用dom4j来解析xml文件

private void readXml(String fileName){
		SAXReader saxReader = new SAXReader();
		Document document  = null;
		try {
			document = saxReader.read(new File(fileName));
			Element root = document.getRootElement();
			for(Iterator rootIter = root.elementIterator("bean"); rootIter.hasNext();){
				Element beanNode = (Element) rootIter.next();
				
				BeanDefinition beanDefinition = new BeanDefinition(beanNode.attributeValue("id"), beanNode.attributeValue("class"));
				
				for(Iterator beanIter = beanNode.elementIterator(); beanIter.hasNext();){
					Element property = (Element) beanIter.next();
					PropertyDefinition propertyDefinition = new PropertyDefinition(property.attributeValue("name"),property.attributeValue("ref"));
					beanDefinition.getProperties().add(propertyDefinition);
				}
				beanDefines.add(beanDefinition);
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
 


2)initBeans()

private void initBeans(){
		for(BeanDefinition bean : beanDefines){
			if(bean.getClassName()!=null && !"".equals(bean.getClassName().trim())){
				try {
					beanDefinitionMap.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());//反射获取实例
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}



3)inject()

private void inject(){
		for(BeanDefinition beanDefinition : beanDefines){
			Object bean = beanDefinitionMap.get(beanDefinition.getId());
			if(bean!=null){
				try {
					PropertyDescriptor [] ps = Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();
					for(PropertyDefinition propertyDefinition : beanDefinition.getProperties()){
						for(PropertyDescriptor propertyDesc : ps){
							if(propertyDesc.getName().equals(propertyDefinition.getName())){
								Method setter = propertyDesc.getWriteMethod();//获取属性的set方法
								if(setter!=null){
									Object value = beanDefinitionMap.get(propertyDefinition.getRef());
									setter.setAccessible(true); //处理private
									setter.invoke(bean, value);//把引用对象注入到属性
								}
								break;
							}
						}
					}
					
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics