在nanowar中引入AOP

2008-02-23 10:01:12来源:互联网 阅读 ()

新老客户大回馈,云服务器低至5折

通过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);

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:Jmeter使用之脚本录制回放

下一篇:利用游标返回结果集的的例子(Oracle 存储过程)