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

在 NanoWar 中引入 AOP 支援:基於 NanoContainer 的擴充實作

     編輯:Java 相關知識

NanoContainer 的 NanoWar 與 Struts 插件完美實現了 IoC 透明化,但標準版缺乏 AOP 支援。本文記錄透過修改核心類、引入攔截器鏈與委派模式,為 NanoWar 增加 AOP 能力的完整實作過程。

設計思路

  • 在 XML 定義中新增 <aspect> 標籤,與 <parameter> 同層級。
  • interceptor 屬性指定攔截器名稱(以標準組件方式註冊)。
  • pointcuts 屬性定義攔截方法過濾運算式(Perl5 正則 + NanoAOP 預定義規則)。
  • 引入 InterceptorDelegate 充當真實攔截器與目標組件的調用橋樑,解決 IoC 初始化階段攔截器實例尚不可用的問題。

核心類修改清單

關鍵代碼片段

XMLContainerBuilder 解析 aspect

private Map createInterceptors(Element element) {
    Map interceptorMap = new HashMap();
    NodeList children = element.getChildNodes();
    for (int i = 0; i < children.getLength(); i++) {
        if (children.item(i) instanceof Element) {
            Element child = (Element) children.item(i);
            if ("aspect".equals(child.getNodeName())) {
                String interceptor = child.getAttribute("interceptor");
                String pointcuts = child.getAttribute("pointcuts");
                interceptorMap.put(interceptor, pointcuts);
            }
        }
    }
    return interceptorMap.isEmpty() ? null : interceptorMap;
}

註冊攔截器

private void registerComponentInterceptor(NanoContainer container, Class component, String pointcuts, String interceptorKey) {
    if (pointcuts == null) pointcuts = "all-methods";
    if (container.getPico() instanceof AspectablePicoContainer) {
        AspectablePicoContainer aspectContainer = (AspectablePicoContainer) container.getPico();
        aspectContainer.registerInterceptor(
            cuts.instancesOf(component),
            getMethodPointcut(pointcuts),
            new InterceptorDelegate(aspectContainer, interceptorKey)
        );
    }
}

InterceptorDelegate 橋樑實現

public class InterceptorDelegate implements dynaop.Interceptor, org.aopalliance.intercept.MethodInterceptor {
    private PicoContainer pico;
    private Object key;

    public InterceptorDelegate(PicoContainer pico, Object key) {
        this.pico = pico; this.key = key;
    }

    public Object intercept(dynaop.Invocation invocation) throws Throwable {
        return ((dynaop.Interceptor) pico.getComponentInstance(key)).intercept(invocation);
    }

    public Object invoke(org.aopalliance.intercept.MethodInvocation invocation) throws Throwable {
        return ((org.aopalliance.intercept.MethodInterceptor) pico.getComponentInstance(key)).invoke(invocation);
    }
}

XML 配置範例

<component class="com.example.ServiceImpl">
  <aspect interceptor="loggingInterceptor" pointcuts="public * *(..)"/>
  <aspect interceptor="txInterceptor" pointcuts="* save*(..), * delete*(..)"/>
</component>

實作心得

  • 修改量較大,採用 Aspectable 前綴新建類別,保持原有邏輯不變,降低風險。
  • InterceptorDelegate 同時實現 dynaop.Interceptor 與 MethodInterceptor,相容 NanoAOP 與 AOP Alliance 兩種 API。
  • Pointcut 解析支援預定義關鍵字(all-methods、get-methods 等)與自訂正則。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
原類別新類別(Aspectable 前綴)關鍵變更
ScopedContainerComposerAspectableScopedContainerComposer建構子使用 DynaopAspectablePicoContainerFactory
XMLContainerBuilderAspectableXMLContainerBuilder解析 <aspect>、註冊攔截器、getMethodPointcut 解析 pointcut
ContainerRecorderAspectableContainerRecordergetContainerProxy() 返回 AspectablePicoContainer 代理
DefaultLifecycleContainerBuilderAspectableLifecycleContainerBuildercreateContainer() 返回 AOP 容器
ServletContainerListenerAspectableServletContainerListenercreateBuilder() 返回 AspectableLifecycleContainerBuilder