EJB中的拦截器
2015-09-29 18:18
309 查看
拦截器可以拦截Session Bean和Message-driven Bean的方法调用或生命周期事件。拦截器用于封装应用的公用行为,使这些行为与业务逻辑分离。拦截器可以使同一bean类中的方法或者是一个外部类。
HelloBean
[java] view
plaincopy
import com.foshanshop.ejb3.HelloChina;
import com.foshanshop.ejb3.HelloChinaRemote;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
@Stateless
@Remote (Hello.class)
@Interceptors(HelloInterceptor.class)
public class HelloBean implements HelloRemote {
public String sayHello(String name) {
return name +"说:你好!.";
}
public String myName() {
return "我是佛山人";
}
}
@Interceptors注释指定一个或多个在外部类中定义的拦截器,多个拦截器用逗号隔开。
上面拦截器HelloInterceptor对HelloBean的所有方法进行拦截。如果你只需对某一方法拦截,你可以在方法上面定义拦截器,如:
[java] view
plaincopy
@Interceptors(HelloInterceptor.class)
public class HelloBean implements HelloRemote {
public String SayHello(String name) {
return name +"说:你好!";
}
}
拦截器HelloInterceptor.java
[java] view
plaincopy
package com.foshanshop.ejb3.impl;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class HelloInterceptor {
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("*** HelloInterceptor intercepting");
long start = System.currentTimeMillis();
try{
if (ctx.getMethod().getName().equals("SayHello")){
System.out.println("*** SayHello 已经被调用! *** " );
}
if (ctx.getMethod().getName().equals("Myname")){
System.out.println("*** Myname 已经被调用! *** " );
}
return ctx.proceed();
}catch (Exception e) {
throw e;
}finally {
long time = System.currentTimeMillis() - start;
System.out.println("用时:"+ time + "ms");
}
}
}
@AroundInvoke注释指定了要用作拦截器的方法,拦截器方法与被拦截的业务方法执行同一个java调用堆栈、同一个事务和安全上下文中。用@AroundInvoke注释指定的方法必须遵守以下格式:
public Object XXX(javax.interceptor.InvocationContext ctx) throws Exception
下面是javax.interceptor.InvocationContext封装了客户端所调用业务方法的一些信息。
[java] view
plaincopy
package javax.interceptor;
public interface InvocationContext{
public Object getTarget();
public Method getMethod();
public Ojbect[] getParameters();
public void setParameters(Object[] newArgs);
public java.util.Map<String, Ojbect> getContextData();
public Object proceed() throws Exception;
}
getTarget() 指向被调用的bean实例
getMethod() 指向被拦截的业务方法
getParameters() 获取被拦截业务方法的参数
setParameters() 设置被拦截业务方法的参数
getContextData() 返回一个Map对象,它在整个方法调用期间都可以被访问到。位于同一个方法调用内的不同拦截器之间可以利用它来传递上下文相关的数据。
在HelloInterceptor代码中,我们调用了ctx.proceed()方法。如果还有其他拦截器未执行,ctx.proceed()方法内部会调用后面拦截器的@AroundInvoke方法。直到后面的拦截器全部执行结束,EJB容器才会执行被拦截的业务方法。另外如果我们想在被拦截的业务方法执行结束后再执行一些自定义的代码,我们可以在ctx.proceed()执行后方法返回前加入自己的代码。
[java]
view plaincopy
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("*** HelloInterceptor intercepting");
long start = System.currentTimeMillis();
try{
if (ctx.getMethod().getName().equals("SayHello")){
System.out.println("*** SayHello 已经被调用! *** " );
}
if (ctx.getMethod().getName().equals("Myname")){
System.out.println("*** Myname 已经被调用! *** " );
}
Object o= ctx.proceed();
//insert your code
return o;
}catch (Exception e) {
throw e;
}finally {
long time = System.currentTimeMillis() - start;
System.out.println("用时:"+ time + "ms");
}
}
}
由于拦截器和被拦截的bean方法同处于一个java调用堆栈中,如果你希望终止方法执行,可以抛出异常。业务方法也告结束。
HelloBean
[java] view
plaincopy
import com.foshanshop.ejb3.HelloChina;
import com.foshanshop.ejb3.HelloChinaRemote;
import javax.ejb.Local;
import javax.ejb.Remote;
import javax.ejb.Stateless;
import javax.interceptor.Interceptors;
@Stateless
@Remote (Hello.class)
@Interceptors(HelloInterceptor.class)
public class HelloBean implements HelloRemote {
public String sayHello(String name) {
return name +"说:你好!.";
}
public String myName() {
return "我是佛山人";
}
}
@Interceptors注释指定一个或多个在外部类中定义的拦截器,多个拦截器用逗号隔开。
上面拦截器HelloInterceptor对HelloBean的所有方法进行拦截。如果你只需对某一方法拦截,你可以在方法上面定义拦截器,如:
[java] view
plaincopy
@Interceptors(HelloInterceptor.class)
public class HelloBean implements HelloRemote {
public String SayHello(String name) {
return name +"说:你好!";
}
}
拦截器HelloInterceptor.java
[java] view
plaincopy
package com.foshanshop.ejb3.impl;
import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
public class HelloInterceptor {
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("*** HelloInterceptor intercepting");
long start = System.currentTimeMillis();
try{
if (ctx.getMethod().getName().equals("SayHello")){
System.out.println("*** SayHello 已经被调用! *** " );
}
if (ctx.getMethod().getName().equals("Myname")){
System.out.println("*** Myname 已经被调用! *** " );
}
return ctx.proceed();
}catch (Exception e) {
throw e;
}finally {
long time = System.currentTimeMillis() - start;
System.out.println("用时:"+ time + "ms");
}
}
}
@AroundInvoke注释指定了要用作拦截器的方法,拦截器方法与被拦截的业务方法执行同一个java调用堆栈、同一个事务和安全上下文中。用@AroundInvoke注释指定的方法必须遵守以下格式:
public Object XXX(javax.interceptor.InvocationContext ctx) throws Exception
下面是javax.interceptor.InvocationContext封装了客户端所调用业务方法的一些信息。
[java] view
plaincopy
package javax.interceptor;
public interface InvocationContext{
public Object getTarget();
public Method getMethod();
public Ojbect[] getParameters();
public void setParameters(Object[] newArgs);
public java.util.Map<String, Ojbect> getContextData();
public Object proceed() throws Exception;
}
getTarget() 指向被调用的bean实例
getMethod() 指向被拦截的业务方法
getParameters() 获取被拦截业务方法的参数
setParameters() 设置被拦截业务方法的参数
getContextData() 返回一个Map对象,它在整个方法调用期间都可以被访问到。位于同一个方法调用内的不同拦截器之间可以利用它来传递上下文相关的数据。
在HelloInterceptor代码中,我们调用了ctx.proceed()方法。如果还有其他拦截器未执行,ctx.proceed()方法内部会调用后面拦截器的@AroundInvoke方法。直到后面的拦截器全部执行结束,EJB容器才会执行被拦截的业务方法。另外如果我们想在被拦截的业务方法执行结束后再执行一些自定义的代码,我们可以在ctx.proceed()执行后方法返回前加入自己的代码。
[java]
view plaincopy
@AroundInvoke
public Object log(InvocationContext ctx) throws Exception {
System.out.println("*** HelloInterceptor intercepting");
long start = System.currentTimeMillis();
try{
if (ctx.getMethod().getName().equals("SayHello")){
System.out.println("*** SayHello 已经被调用! *** " );
}
if (ctx.getMethod().getName().equals("Myname")){
System.out.println("*** Myname 已经被调用! *** " );
}
Object o= ctx.proceed();
//insert your code
return o;
}catch (Exception e) {
throw e;
}finally {
long time = System.currentTimeMillis() - start;
System.out.println("用时:"+ time + "ms");
}
}
}
由于拦截器和被拦截的bean方法同处于一个java调用堆栈中,如果你希望终止方法执行,可以抛出异常。业务方法也告结束。
相关文章推荐
- Centos6/7来网络引导(pxe)安装centos
- General Problem Solving Techniques [Beginner-1]~H - Songs
- DriverStudio工具包介绍
- Python DeprecationWarning 类型错误
- Spring annotation 之lookup (方法注入)
- 如何删除微软拼音输入法2007
- 解决img标签间距问题
- textview属性
- MFC消息机制逆向追踪
- Netcat简介
- 在fragment中添加上下文菜单
- 用jquery动画实现的简单的图片轮播
- word文档左侧显示目录
- UNC Path Convert to Local Path
- Delphi Webbrowser 修改 textarea 值 百度
- 一道小学生题目:红星+星红+星红=爱星星,问:爱、红、星各代表数字几?
- dede 列表页 上一页下一页 只要链接
- hdoj Constructing Roads In JGShining's Kingdom (LIS变形+二分)
- hdu 5493
- Regionals 2007 >> Asia - Nanjing - "Ray, Pass me the dishes!" 线段树 难 uva live 3938