Groovy探索之MOP 十三 Interceptor 三(2)
???????Groovy探索之MOP 十三 Interceptor 三(2) ? ? ? 其实,阻止拦截的使用像在《Groovy探索之MOP 十三 Interceptor 三(1)》中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器。还是上一篇的那个例子: ? class Hello { ??? ??? def hello(name) ??? { ?????? "hello,$name" ??? } ? } ? ? 我们现在明确的把类中所有的方法进行拦截,拦截器如下: ? class AllInterceptor implements Interceptor{ ??? ? ??? Object beforeInvoke(Object object,String methodName,Object[] arguments){ ?????? ?????? println "the function-$methodName is intercepted" ?????? ??? } ??? ??? boolean doInvoke(){ true } ??? ??? Object afterInvoke(Object object,Object[] arguments, ?????????? Object result){ ?????? result ??? } ? } ? ? 在上面的拦截器中,我们在“beforeInvoke”方法中拦截了被拦截对象中的所有方法,打印出哪个方法被拦截的提示出来。 比如,我们做如下的测试代码: ? ? ??? ? ? def proxy= ProxyMetaClass.getInstance( Hello ) ??? ? ?????? proxy.interceptor= new AllInterceptor() ??? ? ? ?????? proxy.use{ ?????????? def hello = new Hello() ?????????? hello.hello('World') ?????? } ? ? ? 运行结果为: the function-ctor is intercepted the function-hello is intercepted ? 表示已经有了两个方法被拦截。现在,我们的客户端不想拦截“hello”方法,在这里我们就可以使用阻止拦截了: ? ??? ? ? def proxy= ProxyMetaClass.getInstance( Hello ) ??? ? ?????? proxy.interceptor= new AllInterceptor() ??? ? ? ?????? proxy.use{ ?????????? def hello = new Hello() ?????????? hello.&hello('World') ?????? } ? ? 运行结果为: the function-ctor is intercepted ? ? 这样就没有对“hello”方法进行拦截。 我们还是需要回忆一下上一篇中遇到的嵌套拦截的问题,即在拦截器中又调用了需要被拦截的那个方法,形成了嵌套拦截的问题。我们在上一篇中的解决方法是使用“&”标识符进行阻止拦截。使用“&”标识符毕竟只能阻止少量的方法进行嵌套拦截,在实际的使用中不是很方便,为了解决这个问题,我们也有一个一劳永逸的解决办法。即我们可以创建一个阻止嵌套拦截器类,让继承它的所有拦截器具备有阻止嵌套拦截的能力。 这个基类如下: ? abstract class UninterceptedInterceptor implements Interceptor{ ??? def proxy= null ??? ??? abstract Object doBefore( Object object, ??? Object[] arguments ) ??? ??? public Object beforeInvoke( Object object, ??? Object[] arguments ){ ?????? proxy.interceptor= null ?????? def result ?????? try{ ?????????? result= doBefore(object,methodName,arguments) ?????? }catch(Exception e){ ?????? throw e ?????? }finally{ ?????????? proxy.interceptor= this ?????? } ?????? result ??? } ??? ??? abstract boolean doInvoke() ??? ??? abstract Object doAfter( Object object, ??? Object result ) ??? ??? public Object afterInvoke( Object object, ??? Object[] arguments,Object result ){ ?????? proxy.interceptor= null ?????? try{ ?????????? result= doAfter(object,arguments,result) ?????? }catch(Exception e){ ?????? throw e ?????? }finally{ ?????????? proxy.interceptor= this ?????? } ?????? result ? } ? } ? 这个基类很简单,可以放到我们的工具包里去。我们只看“beforeInvoke”方法,思想就是,我们的拦截动作都放在“doBefore”方法里,同时,在执行“doBefore”方法的时候,我们使用如下的语句将拦截器去掉: proxy.interceptor= null 当“doBefore”方法完了以后,我们再把拦截器加上,使用下面的语句: proxy.interceptor= this ? 这样,我们需要进行嵌套拦截的类就继承该类,如下: ? class MyInterceptor extends UninterceptedInterceptor{ ??? ??? Object doBefore( Object object, ?????????? Object[] arguments ) ??? { ?????? ??? } ??? ??? boolean doInvoke() ??? { ?????? true ??? } ??? ??? Object doAfter( Object object, ?????????? Object result ) ??? { ?????? if(methodName == 'hello') ?????? { ?????????? result = new Hello().hello('log')+'/n'+result ?????? } ?????? result ??? } ? } ? ? 这个类就更简单了,在它里面进行了拦截方法的嵌套调用,形如下面的语句: if(methodName == 'hello') ?????? { ?????????? result = new Hello().hello('log')+'/n'+result ??? } ? 拦截了“hello”方法,却在里面又进行“hello”方法的调用,一个很明显的嵌套调用。 最后,我们来写点代码测试这个阻止拦截的拦截器: ? ??? ? def proxy= ProxyMetaClass.getInstance( Hello ) ??? ? ?????? proxy.interceptor = new MyInterceptor() ??? ? ??? ? proxy.interceptor.proxy = proxy ??? ? ? ?????? proxy.use{ ?????????? def hello = new Hello() ?????????? println hello.hello('World') ?????? } ??? ? 这也和其他的测试代码大致相似,唯一不同的是下面的语句: proxy.interceptor.proxy = proxy ? 它需要我们给Interceptor对象的“proxy”属性赋值,这在其他的测试代码里是没有的。运行结果为: hello,log hello,World ? 的确起到了阻止拦截的效果。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |