閱讀159 返回首頁    go 阿裏雲 go 技術社區[雲棲]


【設計模式】【用DOM4J模擬spring實現簡單工廠】

package lee;

/**
 * Description:
 * <br/>網站: <a href="https://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="https://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="https://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="https://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="https://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  >
		<!-- 為name屬性注入普通屬性值 -->
		<property name="name" value="李剛的電腦"/>
		<!-- 為out屬性注入普通屬性值 -->
		<property name="out" ref="betterPrinter"/>
	</bean>
	<!-- 配置兩個Bean實例 -->
	<bean  /> 
	<bean  />
	<!-- 配置一個prototype行為的Bean實例 -->
	<bean   scope="prototype"/> <!--①-->
</beans>

<?xml version="1.0" encoding="GBK"?>
<beans>	
	<bean  >
		<!-- 為name屬性注入普通屬性值 -->
		<property name="name" value="李剛的電腦"/>
		<!-- 為out屬性注入普通屬性值 -->
		<property name="out" ref="betterPrinter"/>
	</bean>
	<!-- 配置兩個Bean實例 -->
	<bean  /> 
	<bean  />
	<!-- 配置一個prototype行為的Bean實例 -->
	<bean   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="https://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);
					}
				}
			}
		}
	}
}






最後更新:2017-04-04 07:03:36

  上一篇:go STL之二:vector容器用法詳解
  下一篇:go poj 3687 Labeling Balls 逆向拓撲