首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 使用 dom4j 解析 XML 實現抽象工廠模式完整範例

     編輯:Java 相關知識

展示如何透過 dom4j 解析 XML 設定檔,結合反射機制實現 抽象工廠模式,動態建立 Service 與 DAO 兩大產品族的實例,並以單例快取管理物件生命週期。

XML 設定檔 (beans-config.xml)

<?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)

package com.xxjstgb.drp.util;

import org.dom4j.*;
import org.dom4j.io.SAXReader;
import java.util.*;

public class BeanFactory {
    private static final BeanFactory INSTANCE = new BeanFactory();
    private static final String CONFIG_FILE = "beans-config.xml";

    private final Document doc;
    private final Map<String, Object> serviceCache = new HashMap<>();
    private final Map<String, Object> daoCache = new HashMap<>();

    private BeanFactory() {
        try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(CONFIG_FILE)) {
            if (is == null) throw new RuntimeException("Config not found: " + CONFIG_FILE);
            doc = new SAXReader().read(is);
        } catch (Exception e) {
            throw new RuntimeException("Init BeanFactory failed", e);
        }
    }

    public static BeanFactory getInstance() { return INSTANCE; }

    // 取得 Service 實例(介面 Class 作為鍵)
    public synchronized Object getServiceObject(Class<?> iface) {
        String key = iface.getName();
        if (serviceCache.containsKey(key)) return serviceCache.get(key);

        Element el = (Element) doc.selectSingleNode("//service[@id='" + key + "']");
        if (el == null) throw new RuntimeException("Service config missing: " + key);
        String implClass = el.attributeValue("class");

        Object instance = createInstance(implClass);
        serviceCache.put(key, instance);
        return instance;
    }

    // 取得 DAO 實例
    public synchronized Object getDaoObject(Class<?> iface) {
        String key = iface.getName();
        if (daoCache.containsKey(key)) return daoCache.get(key);

        Element el = (Element) doc.selectSingleNode("//dao[@id='" + key + "']");
        if (el == null) throw new RuntimeException("DAO config missing: " + key);
        String implClass = el.attributeValue("class");

        Object instance = createInstance(implClass);
        daoCache.put(key, instance);
        return instance;
    }

    private Object createInstance(String className) {
        try {
            return Class.forName(className).getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Instantiate failed: " + className, e);
        }
    }

    // 測試主程式
    public static void main(String[] args) {
        ItemManager itemMgr = (ItemManager) getInstance().getServiceObject(ItemManager.class);
        ItemDao itemDao = (ItemDao) getInstance().getDaoObject(ItemDao.class);
        System.out.println("itemManager: " + itemMgr);
        System.out.println("itemDao: " + itemDao);
    }
}

設計亮點與可改進處

優點建議強化
設定與程式碼解耦,換實作無需改碼加入 Bean 生命週期管理 (init/destroy 方法)
單例快取避免重複建立支援 Prototype 作用域(每次新建)
XPath 查詢靈活改用 DOM4J 2.x / StAX 提升解析效能
同步方法保證執行緒安全改用 ConcurrentHashMap + Double-Check Locking 降低鎖爭用

現代替代方案

實務專案建議直接採用成熟 IoC 容器(Spring / Guice / Dagger),提供:

  • 依賴注入 (Constructor/Setter/Field Injection)
  • AOP、事務管理、事件總線
  • 條件裝配、Profile 環境隔離
  • 標準化生命週期回呼 (@PostConstruct, @PreDestroy)

本範例適合教學理解 IoC 核心原理,或極輕量環境無法引入框架時參考。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved