在繼續介紹攔截器類別之前,建議您先參考一下:
像 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
})
onlyfun.caterpillar.LogInterceptor.class,
onlyfun.caterpillar.OtherInterceptor.class
})
當一個Bean上套用多個攔截器類別時,呼叫攔截器的順序就是在@Interceptors中定義的順序,InvocationContext的proceed()執行時,若下一個攔截器,則執行流程是交給下一個攔截器,若無下一個攔截器,則InvocationContext的proceed()執行時,是交給目標(Target)方法。
一個編譯單元中只能有一個@AroundInvoke,所以一個攔截器類別中,只能定義一個攔截方法,若要多個攔截器方法,就是一個類別中定義一個攔截器方法。