159
技術社區[雲棲]
【設計模式】【用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