Groovy探索之MOP 十 Interceptor 二
在本系列的《Groovy探索之MOP 九 Interceptor 一》中,我们已经详细的介绍了一个简单的拦截器类的方方面面,使得我们初步有了拦截器的基础。本篇需要在前面的拦截器类的基础上,进一步用拦截器类来实现我们的AOP编程。
首先,我们在本系列的第一篇中,所拦截的方法都是固定的方法。现在,我们需要把它扩展成由拦截器类的使用者来指定被拦截的方法。
先还是给出需要被拦截的类来:
class Foo {
def test1()
{
println 'test1'
}
def test2()
{
println 'test2'
}
def test3()
{
println 'test3'
}
}
然后来给出我们的拦截器类:
class MethodsInterceptor implements Interceptor{
def methods
Object beforeInvoke(Object object, String methodName, Object[] arguments){
if( methodName in this.methods )
{
println "before invoking $methodName"
}
null
}
boolean doInvoke(){ true }
Object afterInvoke(Object object, String methodName, Object[] arguments,
Object result){
if( methodName in this.methods )
{
println "after invoking $methodName"
}
result
}
}
有了上一篇文字的基础,这个拦截器类就比较好理解了。不同的是,在上一篇文字的拦截器类中,需要拦截的方法是固定的,而这个拦截器所需要拦截的方法却是由属性"methods"来确定的。
来看看我们怎么使用这个拦截器类:
def proxy= ProxyMetaClass.getInstance( Foo )
proxy.interceptor= new MethodsInterceptor(methods:['test1','test2'])
proxy.use{
def f= new Foo()
f.test1()
f.test2()
f.test3()
}
运行结果为:
before invoking test1
test1
after invoking test1
before invoking test2
test2
after invoking test2
test3
有了这个客户给定需要拦截的参数,我们就朝着AOP编程迈进了第一步。
接下来,我们需要该拦截器类不同的类起到拦截作用,这样,我们就可以说,我们初步的完成了一个简单的AOP编程。
下面,我们来做一个简单的帮助类,来使得我们的拦截器可以拦截不同的类:
class InterceptorHelper {
def static intercept(Class clzz,methodNames,Closure closure)
{
def proxy= ProxyMetaClass.getInstance( clzz )
proxy.interceptor= new MethodsInterceptor(methods:methodNames)
proxy.use{
closure.call()
}
}
}
很简单,该工具类需要我们输入三个参数:"clzz"需要拦截的对象的类;"methodNames"需要拦截的方法;"closure"调用那些需要拦截的方法。
下面是测试用例:
InterceptorHelper.intercept(Foo,['test1','test2']){
def f = new Foo()
f.test1()
f.test2()
f.test3()
}
运行结果为:
before invoking test1
test1
after invoking test1
before invoking test2
test2
after invoking test2
test3
为了测试上面的工具类是否能够拦截其他的类,我们特意再做了一个测试,假设有如下的一个类:
class Too {
def test1()
{
println 'too1'
}
def test2()
{
println 'too2'
}
}
我们也来测试一下,看看我们的工具类是否能够拦截这个类:
InterceptorHelper.intercept(Too,['test1','test2']){
def t = new Too()
t.test1()
t.test2()
}
运行结果为:
before invoking test1
too1
after invoking test1
before invoking test2
too2
after invoking test2
可以看到,的确可以拦截不同的类的给定方法了。这样,我们就向着AOP编程迈出了关键性的一步了。以后,我们在实际的编码过程中,我们可能会对我们的拦截器类以及AOP工具提出各种各样的要求。但都可以从我们上面的例子扩展开来。
我们可以去试着实现一下:
我们如何实现对我们在客户端给定的对象实现所有的除构造器和GroovyObject方法外的方法实现拦截。
我们又该如何实现对我们在客户端给定的对象实现由客户端给定一些不需要拦截的方法后,拦截其他的方法。
从这样的各种各样的要求可以看出,实现我们自己的AOP编程的确可以根据项目中的实际要求,达到方便灵活的目的。