Java中dom4j讀取配置文件實現抽象工廠+反射
在Java中也可以同Donet一樣,將差異配置在配置文件里面。另外,我們采用下面的方式實現,將會更加便捷。
邏輯描述:
現在我們想在B層和D層加上接口層,并使用工廠。而我們可以將創建B和創建D看作是兩個系列,然后就可以使用抽象工廠進行創建了。
配置文件:beans-config.xml。service-class與dao-class分別對應兩個系列的產品。子菜單中id對應接口的命名空間,class對應實現類的命名空間。
- [html] view plaincopyprint?
- <?xml version="1.0" encoding="UTF-8"?>
- <beans>
- <service-class>
- <service id="com.xxjstgb.drp.basedata.manager.ItemManager" class="com.xxjstgb.drp.basedata.manager.ItemManagerImpl" />
- <service id="com.xxjstgb.drp.flowcard.manager.FlowCardManager" class="com.xxjstgb.drp.flowcard.manager.impl.FlowCardManagerImpl" />
- </service-class>
- <dao-class>
- <dao id="com.xxjstgb.drp.basedata.dao.ItemDao" class="com.xxjstgb.drp.basedata.dao.ItemDao4OracleImpl" />
- <dao id="com.xxjstgb.drp.flowcard.dao.FlowCardDao" class="com.xxjstgb.drp.flowcard.dao.impl.FlowCardDaoImpl" />
- </dao-class>
- </beans>
抽象工廠:BeanFactory。通過讀取配置文件,取得相關對象,并將相關創建好的對象保存在Map中。
- [java] view plaincopyprint?
- package com.xxjstgb.drp.util;
- import java.util.HashMap;
- import java.util.Map;
- //dom4j
- import org.dom4j.Document;
- import org.dom4j.DocumentException;
- import org.dom4j.Element;
- import org.dom4j.io.SAXReader;
- import com.xxjstgb.drp.basedata.dao.ItemDao;
- import com.xxjstgb.drp.basedata.manager.ItemManager;
- import com.xxjstgb.drp.flowcard.dao.FlowCardDao;
- import com.xxjstgb.drp.flowcard.manager.FlowCardManager;
- /**
- * 抽象工廠,主要創建兩個系列的產品
- * 1、Manager系列
- * 2、Dao系列產品
- * @author liuzhengquan
- *
- */
- public class BeanFactory {
- private static BeanFactory instance=new BeanFactory();
- //系統缺省配置文件名稱
- private final String beansConfigFile="beans-config.xml";
- //保存Dao相關對象
- private Document doc;
- /*
- * key=配置文件中的id值
- * value=對應了該Id的對象
- */
- private Map serviceMap = new HashMap();//保存Service相關對象
- private Map daoMap = new HashMap();//保存Dao相關對象
- private BeanFactory(){
- try {
- doc=new SAXReader().read(Thread.currentThread().getContextClassLoader().getResourceAsStream(beansConfigFile));
- } catch (DocumentException e) {
- e.printStackTrace();
- throw new RuntimeException();
- }
- }
- public static BeanFactory getInstance(){
- return instance;
- }
- /**
- * 根據產品編號取得Service系列產品
- * @param serviceId
- * @return
- */
- public synchronized Object getServiceObject(Class c){
- //如果存在相關對象實例,返回
- if(serviceMap.containsKey(c.getName())){
- return serviceMap.get(c.getName());
- }
- Element beanElt=(Element)doc.selectSingleNode("//service[@id=\""+ c.getName() + "\"]");
- String className=beanElt.attributeValue("class");
- Object service=null;
- try {
- service=Class.forName(className).newInstance();
- //將創建好的對象放到Map中
- serviceMap.put(c.getName(), service);
- } catch (Exception e) {
- throw new RuntimeException();
- }
- return service;
- }
- /**
- * 根據產品編號取得Dao系列產品
- * @param daoId
- * @return
- */
- public synchronized Object getDaoObject(Class c){
- //如果存在相關對象實例,返回
- if(daoMap.containsKey(c.getName())){
- return daoMap.get(c.getName());
- }
- Element beanElt=(Element)doc.selectSingleNode("//dao[@id=\""+c.getName()+"\"]");
- String className=beanElt.attributeValue("class");
- Object dao=null;
- try {
- dao=Class.forName(className).newInstance();
- //將創建好的對象放到Map中
- daoMap.put(c.getName(), dao);
- } catch (Exception e) {
- throw new RuntimeException();
- }
- return dao;
- }
- /**
- * 測試
- * @param args
- */
- public static void main(String[] args){
- ItemManager itemManager=(ItemManager)BeanFactory.getInstance().getServiceObject(ItemManager.class);
- System.out.println("itemManager"+itemManager);
- ItemDao itemDao=(ItemDao)BeanFactory.getInstance().getDaoObject(ItemDao.class);
- System.out.println("itemDao:"+itemDao);
- FlowCardManager flowCardManager=(FlowCardManager)BeanFactory.getInstance().getServiceObject(FlowCardManager.class);
- //FlowCardManager flowCardManager=new FlowCardManagerImpl();
- System.out.println(flowCardManager);
- FlowCardDao flowCardDao=(FlowCardDao)BeanFactory.getInstance().getDaoObject(FlowCardDao.class);
- //FlowCardDao flowCardDao=new FlowCardDaoImpl();
- System.out.println("flowCardDao:"+flowCardDao);
- }
- }
運行結果:
總結:
通過抽象工廠+反射的實現,調用層就可以只認識接口,而無須與具體實現打交道,實現了解耦合。同時,由于配置文件里面是接口和實現的命名空間,我們就可以用相應接口的.class屬性,點出命名空間,將配置文件的id和class都以鍵值對的形式配置在Map中,實現反射。
原文鏈接:http://blog.csdn.net/liu765023051/article/details/8986629