【设计模式】【用DOM4J模拟spring实现简单工厂】

  1. 云栖社区>
  2. 博客>
  3. 正文

【设计模式】【用DOM4J模拟spring实现简单工厂】

广贤 2013-01-16 17:29:00 浏览1202
展开阅读全文
package lee;

/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public interface Output
{
	//接口里定义的属性只能是常量
	int MAX_CACHE_LINE = 50;
	//接口里定义的只能是public的抽象实例方法
	void out();
	void getData(String msg);
}



package lee;
/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */

//让Printer类实现Output
public class Printer implements Output
{
	private String[] printData = new String[MAX_CACHE_LINE];
	//用以记录当前需打印的作业数
	private int dataNum = 0;
	public void out()
	{
		//只要还有作业,继续打印
		while(dataNum > 0)
		{
			System.out.println("打印机打印:" + printData[0]);
			//把作业队列整体前移一位,并将剩下的作业数减1
			System.arraycopy(printData , 1, printData, 0, --dataNum);
		}
	}
	public void getData(String msg)
	{
		if (dataNum >= MAX_CACHE_LINE)
		{
			System.out.println("输出队列已满,添加失败");
		}
		else
		{
			//把打印数据添加到队列里,已保存数据的数量加1。
			printData[dataNum++] = msg;
		}
	}
}


package lee;

/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class BetterPrinter implements Output
{
	private String[] printData = new String[MAX_CACHE_LINE * 2];
	//用以记录当前需打印的作业数
	private int dataNum = 0;
	public void out()
	{
		//只要还有作业,继续打印
		while(dataNum > 0)
		{
			System.out.println("高速打印机正在打印:" + printData[0]);
			//把作业队列整体前移一位,并将剩下的作业数减1
			System.arraycopy(printData , 1, printData, 0, --dataNum);
		}
	}
	public void getData(String msg)
	{
		if (dataNum >= MAX_CACHE_LINE * 2)
		{
			System.out.println("输出队列已满,添加失败");
		}
		else
		{
			//把打印数据添加到队列里,已保存数据的数量加1。
			printData[dataNum++] = msg;
		}
	}
}



package lee;

/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class BetterPrinter implements Output
{
	private String[] printData = new String[MAX_CACHE_LINE * 2];
	//用以记录当前需打印的作业数
	private int dataNum = 0;
	public void out()
	{
		//只要还有作业,继续打印
		while(dataNum > 0)
		{
			System.out.println("高速打印机正在打印:" + printData[0]);
			//把作业队列整体前移一位,并将剩下的作业数减1
			System.arraycopy(printData , 1, printData, 0, --dataNum);
		}
	}
	public void getData(String msg)
	{
		if (dataNum >= MAX_CACHE_LINE * 2)
		{
			System.out.println("输出队列已满,添加失败");
		}
		else
		{
			//把打印数据添加到队列里,已保存数据的数量加1。
			printData[dataNum++] = msg;
		}
	}
}



package lee;

import org.crazyit.ioc.*;
/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class IoCTest
{
	public static void main(String[] args) 
		throws Exception
	{
		//创建IoC容器
		ApplicationContext ctx = 
			new YeekuXmlApplicationContext("bean.xml");
		//从IoC容器中取出computer Bean
		Computer c = (Computer)ctx.getBean("computer");
		//测试Computer对象
		c.keyIn("轻量级Java EE企业应用实战");
		c.keyIn("疯狂Java讲义");
		c.print();
		System.out.println(ctx.getBean("now"));
	}
}


<?xml version="1.0" encoding="GBK"?>
<beans>	
	<bean id="computer" class="lee.Computer">
		<!-- 为name属性注入普通属性值 -->
		<property name="name" value="李刚的电脑"/>
		<!-- 为out属性注入普通属性值 -->
		<property name="out" ref="betterPrinter"/>
	</bean>
	<!-- 配置两个Bean实例 -->
	<bean id="printer" class="lee.Printer"/> 
	<bean id="betterPrinter" class="lee.BetterPrinter"/>
	<!-- 配置一个prototype行为的Bean实例 -->
	<bean id="now" class="java.util.Date" scope="prototype"/> <!--①-->
</beans>

<?xml version="1.0" encoding="GBK"?>
<beans>	
	<bean id="computer" class="lee.Computer">
		<!-- 为name属性注入普通属性值 -->
		<property name="name" value="李刚的电脑"/>
		<!-- 为out属性注入普通属性值 -->
		<property name="out" ref="betterPrinter"/>
	</bean>
	<!-- 配置两个Bean实例 -->
	<bean id="printer" class="lee.Printer"/> 
	<bean id="betterPrinter" class="lee.BetterPrinter"/>
	<!-- 配置一个prototype行为的Bean实例 -->
	<bean id="now" class="java.util.Date" scope="prototype"/> <!--①-->
</beans>



package org.crazyit.ioc;

import java.lang.reflect.*;
import java.util.*;
import java.io.*;
import org.dom4j.*;
import org.dom4j.io.*;

/**
 * Description:
 * <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a> 
 * <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
 * <br/>This program is protected by copyright laws.
 * <br/>Program Name:
 * <br/>Date:
 * @author  Yeeku.H.Lee kongyeeku@163.com
 * @version  1.0
 */
public class YeekuXmlApplicationContext
	implements ApplicationContext
{
	//保存容器中所有单例模式的Bean实例
	private Map<String , Object> objPool
		= Collections.synchronizedMap(new HashMap<String , Object>()); 
	//保存配置文件对应的Document对象
	private Document doc;
	//保存配置文件里的根元素
	private Element root;
	public YeekuXmlApplicationContext(String filePath)
		throws Exception
	{
		SAXReader reader = new SAXReader();
		doc = reader.read(new File(filePath));
		root = doc.getRootElement();
		initPool();
		initProp();
	}

	public Object getBean(String name)
		throws Exception
	{
		Object target = objPool.get(name);
		//对于singleton Bean,容器已经初始化了所有Bean实例
		if (target.getClass() != String.class)
		{
			return target;
		}
		else
		{
			String clazz = (String)target;
			//对于prototype并未注入属性值
			return Class.forName(clazz).newInstance();
		}
	}
	//初始化容器中所有singleton Bean
	private void initPool()
		throws Exception
	{
		//遍历配置文件里的每个<bean.../>元素
		for (Object obj : root.elements())
		{
			Element beanEle = (Element)obj;
			//取得<bean.../>元素的id属性
			String beanId = beanEle.attributeValue("id");
			//取得<bean.../>元素的class属性
			String beanClazz = beanEle.attributeValue("class");
			//取得<bean.../>元素的scope属性
			String beanScope = beanEle.attributeValue("scope");
			//如果<bean.../>元素的scope属性不存在,或为singleton
			if (beanScope == null ||
				beanScope.equals("singleton"))
			{
				//以默认构造器创建Bean实例,并将其放入objPool中
				objPool.put(beanId , Class.forName(beanClazz).newInstance());
			}
			else
			{
				//对于非singlton Bean,存放该Bean实现类的类名。
				objPool.put(beanId , beanClazz);
			}
		}
	}
	//初始化容器中singleton Bean的属性
	private void initProp()
		throws Exception
	{
		//遍历配置文件里的每个<bean.../>元素
		for (Object obj : root.elements())
		{
			Element beanEle = (Element)obj;
			//取得<bean.../>元素的id属性
			String beanId = beanEle.attributeValue("id");
			//取得<bean.../>元素的scope属性
			String beanScope = beanEle.attributeValue("scope");
			//如果<bean.../>元素的scope属性不存在,或为singleton
			if (beanScope == null ||
				beanScope.equals("singleton"))
			{
				//取出objPool的指定的Bean实例
				Object bean = objPool.get(beanId);
				//遍历<bean.../>元素的每个<property.../>子元素
				for (Object prop : beanEle.elements())
				{
					Element propEle = (Element)prop;
					//取得<property.../>元素的name属性	
					String propName = propEle.attributeValue("name");
					//取得<property.../>元素的value属性
					String propValue = propEle.attributeValue("value");
					//取得<property.../>元素的ref属性	
					String propRef = propEle.attributeValue("ref");
					//将属性名的首字母大写
					String propNameCamelize = propName.substring(0 , 1).toUpperCase()
						+ propName.substring(1 , propName.length());
					//如果<property.../>元素的value属性值存在
					if (propValue != null && propValue.length() > 0)
					{
						//获取设值注入所需的setter方法
						Method setter = bean.getClass().getMethod(
							"set" + propNameCamelize , String.class);
						//执行setter注入
						setter.invoke(bean , propValue);
					}
					if (propRef != null && propRef.length() > 0)
					{
						//取得需要被依赖注入的Bean实例
						Object target = objPool.get(propRef);
						//objPool池中不存在指定Bean实例
						if (target == null)
						{
							//此处还应处理Singleton Bean依赖prototype Bean的情形
						}
						//定义设值注入所需的setter方法
						Method setter = null;
						//遍历target对象所所实现的所有接口
						for (Class superInterface : target.getClass().getInterfaces())
						{
							try
							{
								//获取设值注入所需的setter方法
								setter = bean.getClass().getMethod(
									"set" + propNameCamelize , superInterface);
								//如果成功取得该接口对应的方法,直接跳出循环
								break;
							}
							catch (NoSuchMethodException ex)
							{
								//如果没有找到对应的setter方法,继续下次循环
								continue;
							}
						}
						//如果setter方法依然为null,
						//则直接取得target实现类对应的setter方法
						if (setter == null)
						{
							setter = bean.getClass().getMethod(
								"set" + propNameCamelize , target.getClass());
						}
						//执行setter注入
						setter.invoke(bean , target);
					}
				}
			}
		}
	}
}






网友评论

登录后评论
0/500
评论
广贤
+ 关注