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

来源:互联网 发布:php会员管理源码 编辑:程序博客网 时间:2024/06/10 14:37
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类实现Outputpublic 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]);//把作业队列整体前移一位,并将剩下的作业数减1System.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]);//把作业队列整体前移一位,并将剩下的作业数减1System.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]);//把作业队列整体前移一位,并将剩下的作业数减1System.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 BeanComputer 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 YeekuXmlApplicationContextimplements 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 Beanprivate 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属性不存在,或为singletonif (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属性不存在,或为singletonif (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);}}}}}}