在nanowar中引入AOP

博客讲述了nanocontainer的nanowar虽实现IoC模式透明,但无法引入nanoaop。作者决定为nanowar添加AOP支持,介绍了引入interceptor chains及<aspect>标签,还说明了需修改的类,以及引入新的通用拦截器类InterceptorDelegate等实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

通过nanocontainer的nanowar和其struts插件完美的实现了IoC模式的透明,但无法在标准的nanowar中引入nanoaop不得不说是一种遗憾。看了一下nanocontainer的代码,决定自己动手给nanowar添加aop的支持。要在组件和实例中支持AOP,首先要引入interceptor chains。可以考虑在XML定义中引入
<aspect interceptor='InterceptorName' pointcuts='Filter'/>标签。这个<aspect>标签与组件或实例的<parameter>标签在同一级别上。其中interceptor指出拦截器的名称。拦截器的实现可以通过标准组件方式在同一个配置文件中进行注册。pointcuts是拦截方法的过滤表达式(perl5的正则表达式,和nanoaop预定义几个过滤规则)。

在nanowar中实现这个<aspect>标签,需要修改ScopedCotainerComposer, XMLContainerBuilder, ContainerRecorder, ServletContainerListener, DefaultLifecycleContainerBuider类。由于拦截器无法在IoC容器初始化的过程中得到实例。因此,还需要引入一个新的通用拦截器类(InterceptorDelegate),作为真正的拦截器实例和需被拦截的组件的调用桥梁。由于对源代码改动量较大,索性就在原来类的前面加上Aspectable前缀引入新的类,但除了AOP部分,其他的保持不变。


ScopedCotainerComposer => AspectableScopedContainerComposer.java

    public AspectableScopedContainerComposer() throws ClassNotFoundException {
        this(new DynaopAspectablePicoContainerFactory().createContainer());
    }

XMLContainerBuilder => AspectableXMLContainerBuilder.java

protected PicoContainer createContainerFromScript(
 ....
            AspectablePicoContainerFactory containerFactory = new DynaopAspectablePicoContainerFactory();
            AspectablePicoContainer childContainer = containerFactory
                    .createContainer(componentAdapterFactory, parentContainer);
            cuts = childContainer.getPointcutsFactory();
 ....
}

    private void registerComponentImplementation(NanoContainer container,
            Element element) throws ClassNotFoundException,
            MalformedURLException {
    ......
    Map interceptors = createInterceptors(element);
    ......
     if (interceptors != null) {
            registerComponentInterceptor(container, clazz, interceptors);
        }
    }
    .......
    private void registerComponentInterceptor(NanoContainer container,
            Class component, String pointcuts, String interceptorKey) {
        if (notSet(pointcuts)) {
            pointcuts = ALL_METHODS;
        }

        if (container.getPico() instanceof AspectablePicoContainer) {
            AspectablePicoContainer aspectContainer = (AspectablePicoContainer) container
                    .getPico();
            aspectContainer.registerInterceptor(cuts.instancesOf(component),
                    getMethodPointcut(pointcuts), new InterceptorDelegate(
                            aspectContainer, interceptorKey));
        }
    }
.......
    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 childElement = (Element) children.item(i);
                if (ASPECT.equals(childElement.getNodeName())) {
                    String interceptor = childElement.getAttribute(INTERCEPTOR);
                    if (notSet(interceptor))
                        throw new NanoContainerMarkupException("'" + KEY
                                + "' attribute not specified for "
                                + element.getNodeName());
                    String pointcuts = childElement.getAttribute(POINTCUTS);
                    interceptorMap.put(interceptor, pointcuts);
                }
            }
        }

        if (interceptorMap.isEmpty())
            return null;
        else
            return interceptorMap;
    }

    private MethodPointcut getMethodPointcut(String pointcuts) {
        if (OBJECT_METHODS.equals(pointcuts))
            return cuts.objectMethods();

        if (IS_METHODS.equals(pointcuts))
            return cuts.isMethods();

        if (ALL_METHODS.equals(pointcuts))
            return cuts.allMethods();

        if (GET_METHODS.equals(pointcuts))
            return cuts.getMethods();

        if (SET_METHODS.equals(pointcuts))
            return cuts.setMethods();

        return cuts.signature(pointcuts);
    }

ContainerRecorder => AspectableContainerRecorder.java

    public MutablePicoContainer getContainerProxy() {
        if (this.container instanceof AspectablePicoContainer)
            return (MutablePicoContainer) Proxy.newProxyInstance(getClass().getClassLoader(),
                    new Class[]{AspectablePicoContainer.class}, invocationRecorder);
        else
            return (MutablePicoContainer) Proxy.newProxyInstance(getClass().getClassLoader(),
                new Class[]{MutablePicoContainer.class}, invocationRecorder);
    }

DefaultLifecycleContainerBuider => AspectableLifecycleContainerBuider.java

    protected PicoContainer createContainer(PicoContainer parentContainer, Object assemblyScope) {
        AspectablePicoContainerFactory containerFactory = new DynaopAspectablePicoContainerFactory();
        return containerFactory.createContainer(parentContainer);
    }

ServletContainerListener => AspectableServletContainerListener.java

private ContainerBuilder createBuilder(ServletContext context)
            throws ClassNotFoundException {
    ......
    if (initParameter.equals(CONTAINER_COMPOSER)) {
        ContainerComposer containerComposer =
                createContainerComposer(context);
             return new AspectableLifecycleContainerBuilder(containerComposer);
        }

InterceptorDelegate .java

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.picocontainer.PicoContainer;

import dynaop.Interceptor;
import dynaop.Invocation;


public class InterceptorDelegate implements Interceptor, MethodInterceptor {

    private PicoContainer pico;
    private Object key;
   
    public InterceptorDelegate(PicoContainer pico, Object key) {
        this.pico = pico;
        this.key = key;
       
    }
    /* (non-Javadoc)
     * @see dynaop.Interceptor#intercept(dynaop.Invocation)
     */
    public Object intercept(Invocation invocation) throws Throwable {
        return ((Interceptor)pico.getComponentInstance(key)).intercept(invocation);
    }

    /* (non-Javadoc)
     * @see org.aopalliance.intercept.MethodInterceptor#invoke(org.aopalliance.intercept.MethodInvocation)
     */
    public Object invoke(MethodInvocation invocation) throws Throwable {
        return ((MethodInterceptor)pico.getComponentInstance(key)).invoke(invocation);
    }
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值