程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Groovy >> Groovy探索之MOP 十三 Interceptor 三(2)

Groovy探索之MOP 十三 Interceptor 三(2)

編輯:Groovy

其實,阻止攔截的使用像在《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, String methodName, 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, String methodName,
Object[] arguments )
public Object beforeInvoke( Object object, String methodName,
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, String methodName, Object[] arguments,
Object result )
public Object afterInvoke( Object object, String methodName,
Object[] arguments, Object result ){
proxy.interceptor= null
try{
result= doAfter(object, methodName, 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, String methodName,
Object[] arguments )
{

}
boolean doInvoke()
{
true
}
Object doAfter( Object object, String methodName, Object[] arguments,
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

的確起到了阻止攔截的效果。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved