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

利用反射實現 EJB 動態委派模式

     編輯:Java 相關知識

痛點:重複的 Delegate 代碼

傳統模式下,每個 Session Bean 需對應一個 Delegate 類,手工封裝所有 public 方法,不僅工作量大,且若後續從 EJB 遷移至 JDO/Hibernate 等持久層,所有 Delegate 皆需修改,維護成本極高。

解決方案:反射動態代理

設計抽象基類 FacadeDelegate 統一處理 Home 查找與代理調用,具體 Delegate 僅需聲明介面,運行期透過反射動態路由至目標 Bean。

核心架構

1. 統一 Home 定位器

public abstract class FacadeDelegate {
    private static String type = Resource.RemoteType;

    public EJBHome getHome(String jndiName, Class homeClass) {
        ServerLocatorAdapter adapter = ServerLocatorAdapter.getInstance();
        return (EJBHome) adapter.getHome(type, jndiName, homeClass);
    }
}

2. 適配器模式隔離 Local/Remote 差異

public class ServerLocatorAdapter {
    private Map cache = Collections.synchronizedMap(new HashMap());
    private static ServerLocatorAdapter me;

    public Object getHome(String type, String jndiName, Class homeClass) throws Exception {
        if (cache.containsKey(jndiName)) return cache.get(jndiName);
        Object home = Resource.LocalType.equals(type)
            ? getLocalHome(jndiName, homeClass)
            : getRemoteHome(jndiName, homeClass);
        cache.put(jndiName, home);
        return home;
    }
    // 利用反射動態實例化 LocalServerLocator / RemoteServerLocator
    private Object getLocalHome(...) { ... Class.forName(Resource.LocalClass) ... }
    private Object getRemoteHome(...) { ... Class.forName(Resource.RemoteClass) ... }
}

3. Resource 配置驅動

所有類名、方法名、JNDI 前綴集中在 Resource 屬性文件,實現「零代碼修改」切換部署模式。

動態委派調用流程

  1. 客戶端調用 Delegate.method(args)。
  2. Delegate 基類透過反射獲取目標 Bean 的 EJBObject(create/findByPrimaryKey)。
  3. 再次反射調用 Bean 上的同名方法,返回結果。

遷移優勢

  • 新增持久層實現(如 JDO)只需提供新的 ServerLocator 實現與配置,無需修改業務 Delegate。
  • 統一異常處理、事務邊界、日誌攔截均可在基類實現。
  • 大幅減少樣板代碼,提升團隊開發效率。

代碼片段:Local/Remote 定位器

public class LocalServerLocator {
    private Context ic; private Map cache;
    public EJBLocalHome getLocalHome(String jndi, Class clazz) {
        if (cache.containsKey(jndi)) return (EJBLocalHome) cache.get(jndi);
        Object ref = ic.lookup(jndi);
        EJBLocalHome home = (EJBLocalHome) ref;
        cache.put(jndi, home);
        return home;
    }
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved