Java中通过dom4j读取配置文件实现抽象工厂+反射

在Donet中实现反射的主要原理是:将差异配置在config配置文件里面,并利用接口,通过在U的bin路径下面找到具体实现的名字来使程序运行。

在Java中也可以同Donet一样,将差异配置在配置文件里面。另外,我们采用下面的方式实现,将会更加便捷。

逻辑描述:

现在我们想在B层和D层加上接口层,并使用工厂。而我们可以将创建B和创建D看作是两个系列,然后就可以使用抽象工厂进行创建了。

配置文件:beans-config.xml。service-class与dao-class分别对应两个系列的产品。子菜单中id对应接口的命名空间,class对应实现类的命名空间。

[html]  view plain copy print ?
  1. <?xml version="1.0" encoding="UTF-8"?>  
  2. <beans>  
  3.      <service-class>  
  4.         <service id="com.xxjstgb.drp.basedata.manager.ItemManager" class="com.xxjstgb.drp.basedata.manager.ItemManagerImpl" />  
  5.         <service id="com.xxjstgb.drp.flowcard.manager.FlowCardManager" class="com.xxjstgb.drp.flowcard.manager.impl.FlowCardManagerImpl" />  
  6.      </service-class>  
  7.      <dao-class>  
  8.         <dao id="com.xxjstgb.drp.basedata.dao.ItemDao" class="com.xxjstgb.drp.basedata.dao.ItemDao4OracleImpl" />  
  9.         <dao id="com.xxjstgb.drp.flowcard.dao.FlowCardDao" class="com.xxjstgb.drp.flowcard.dao.impl.FlowCardDaoImpl" />  
  10.      </dao-class>  
  11. </beans>  


抽象工厂:BeanFactory。通过读取配置文件,取得相关对象,并将相关创建好的对象保存在Map中。

[java]  view plain copy print ?
  1. package com.xxjstgb.drp.util;  
  2.   
  3. import java.util.HashMap;  
  4. import java.util.Map;  
  5.   
  6. //dom4j  
  7. import org.dom4j.Document;  
  8. import org.dom4j.DocumentException;  
  9. import org.dom4j.Element;  
  10. import org.dom4j.io.SAXReader;  
  11.   
  12. import com.xxjstgb.drp.basedata.dao.ItemDao;  
  13. import com.xxjstgb.drp.basedata.manager.ItemManager;  
  14. import com.xxjstgb.drp.flowcard.dao.FlowCardDao;  
  15. import com.xxjstgb.drp.flowcard.manager.FlowCardManager;  
  16.   
  17. /** 
  18.  * 抽象工厂,主要创建两个系列的产品 
  19.  * 1、Manager系列 
  20.  * 2、Dao系列产品 
  21.  * @author liuzhengquan 
  22.  * 
  23.  */  
  24. public class BeanFactory {  
  25.       
  26.     private static BeanFactory instance=new BeanFactory();  
  27.       
  28.     //系统缺省配置文件名称  
  29.     private final String beansConfigFile="beans-config.xml";  
  30.       
  31.     //保存Dao相关对象  
  32.     private Document doc;  
  33.       
  34.     /* 
  35.      * key=配置文件中的id值 
  36.      * value=对应了该Id的对象 
  37.      */  
  38.     private Map serviceMap = new HashMap();//保存Service相关对象  
  39.     private Map daoMap = new HashMap();//保存Dao相关对象  
  40.       
  41.       
  42.     private BeanFactory(){  
  43.         try {  
  44.             doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile));  
  45.         } catch (DocumentException e) {  
  46.             e.printStackTrace();  
  47.             throw new RuntimeException();  
  48.         }  
  49.     }  
  50.       
  51.     public static BeanFactory getInstance(){  
  52.         return instance;  
  53.     }  
  54.       
  55.     /** 
  56.      * 根据产品编号取得Service系列产品 
  57.      * @param serviceId 
  58.      * @return 
  59.      */  
  60.     public synchronized Object getServiceObject(Class c){  
  61.         //如果存在相关对象实例,返回  
  62.         if(serviceMap.containsKey(c.getName())){  
  63.             return serviceMap.get(c.getName());  
  64.         }  
  65.         Element beanElt=(Element)doc.selectSingleNode("//service[@id=\""+ c.getName() + "\"]");  
  66.         String className=beanElt.attributeValue("class");  
  67.         Object service=null;  
  68.           
  69.         try {  
  70.             service=Class.forName(className).newInstance();  
  71.               
  72.             //将创建好的对象放到Map中  
  73.             serviceMap.put(c.getName(), service);  
  74.         } catch (Exception e) {  
  75.             throw new RuntimeException();  
  76.         }  
  77.         return service;  
  78.     }  
  79.       
  80.     /** 
  81.      * 根据产品编号取得Dao系列产品 
  82.      * @param daoId 
  83.      * @return 
  84.      */  
  85.     public synchronized Object getDaoObject(Class c){  
  86.         //如果存在相关对象实例,返回  
  87.         if(daoMap.containsKey(c.getName())){  
  88.             return daoMap.get(c.getName());  
  89.         }  
  90.         Element beanElt=(Element)doc.selectSingleNode("//dao[@id=\""+c.getName()+"\"]");  
  91.         String className=beanElt.attributeValue("class");  
  92.         Object dao=null;  
  93.           
  94.         try {  
  95.             dao=Class.forName(className).newInstance();  
  96.               
  97.             //将创建好的对象放到Map中  
  98.             daoMap.put(c.getName(), dao);  
  99.         } catch (Exception e) {  
  100.             throw new RuntimeException();  
  101.         }  
  102.         return dao;  
  103.     }  
  104.       
  105.       
  106.     /** 
  107.      * 测试 
  108.      * @param args 
  109.      */  
  110.     public static void main(String[] args){  
  111.         ItemManager itemManager=(ItemManager)BeanFactory.getInstance().getServiceObject(ItemManager.class);  
  112.         System.out.println("itemManager"+itemManager);  
  113.           
  114.         ItemDao itemDao=(ItemDao)BeanFactory.getInstance().getDaoObject(ItemDao.class);  
  115.         System.out.println("itemDao:"+itemDao);  
  116.           
  117.         FlowCardManager flowCardManager=(FlowCardManager)BeanFactory.getInstance().getServiceObject(FlowCardManager.class);  
  118.         //FlowCardManager flowCardManager=new FlowCardManagerImpl();  
  119.         System.out.println(flowCardManager);  
  120.           
  121.         FlowCardDao flowCardDao=(FlowCardDao)BeanFactory.getInstance().getDaoObject(FlowCardDao.class);  
  122.         //FlowCardDao flowCardDao=new FlowCardDaoImpl();  
  123.         System.out.println("flowCardDao:"+flowCardDao);  
  124.     }  
  125.       
  126. }  

运行结果:


总结:

通过抽象工厂+反射的实现,调用层就可以只认识接口,而无须与具体实现打交道,实现了解耦合。同时,由于配置文件里面是接口和实现的命名空间,我们就可以用相应接口的.class属性,点出命名空间,将配置文件的id和class都以键值对的形式配置在Map中,实现反射。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值