攔截器類別


在繼續介紹攔截器類別之前,建議您先參考一下:

Bean 中的攔截器 中的日誌例子,為與商務邏輯無關的系統服務,最好是避免直接撰寫在商務邏輯的方法或Bean中,以免減少可移植性,您可以另外定義一個攔截器類別,例如:
  • LogInterceptor.java
package onlyfun.caterpillar;

import java.util.logging.*;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;

public class LogInterceptor {
@AroundInvoke
public Object logHello(InvocationContext context) throws Exception {
String methodName = context.getMethod().getName();
String message = (String) context.getParameters()[0];

StringBuilder builder = new StringBuilder();
builder.append("Method:");
builder.append(methodName);
builder.append("\nMessage: ");
builder.append(message);

try {
return context.proceed();
} finally {
Logger.getLogger(HelloBeanImpl.class.getName())
.log(Level.INFO, builder.toString());
}
}
}

這個類別中,移植了 Bean 中的攔截器 中的logHello(),而您的HelloBeanImpl就可以恢復如下:
  • HelloBeanImpl.java
package onlyfun.caterpillar;

import javax.ejb.Stateless;
import javax.interceptor.Interceptors;

@Stateless(name="ejb/HelloFacade")
@Interceptors({onlyfun.caterpillar.LogInterceptor.class})
public class HelloBeanImpl implements HelloBean {
public String doHello(String message) {
return message + "processed....";
}
}

您要使用@Interceptors標註這個Bean將套用哪些攔截器,到這邊,執行的結果與 Bean 中的攔截器 中的結果無異。

若您要套用多個攔截器至Bean上,則可以使用逗號加以區隔,例如:
@Interceptors({
    onlyfun.caterpillar.LogInterceptor.class,
    onlyfun.caterpillar.OtherInterceptor.class
})

當一個Bean上套用多個攔截器類別時,呼叫攔截器的順序就是在@Interceptors中定義的順序,InvocationContext的proceed()執行時,若下一個攔截器,則執行流程是交給下一個攔截器,若無下一個攔截器,則InvocationContext的proceed()執行時,是交給目標(Target)方法。

一個編譯單元中只能有一個@AroundInvoke,所以一個攔截器類別中,只能定義一個攔截方法,若要多個攔截器方法,就是一個類別中定義一個攔截器方法。