会话EJB系列(五)拦截器

本文深入介绍了EJB3拦截器的用途、作用与Spring AOP的对比,并通过示例展示了拦截器的初步使用方法。重点突出了如何将通用逻辑从业务方法中抽离出来,提高代码复用性和可维护性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文主题‘拦截器’,详细介绍其用途、作用、与Spring框架AOP的对比,并介绍其初步用法。

  

 一.简介

        企业级应用中经常面对的事务管理、安全检查、缓存、对象池管理等,为此Spring框架提供了AOP方式,灵活控制业务方法!而EJB3没有提供AOP支持,那么他又是如何应对的呢?

 

       JavaEE规范中提供的横切性服务:事务管理和安全检查。

       EJB容器实现JavaEE规范

               用CMT解决事务管理问题

               用JAAS以声明的方式解决安全检查,权限控制。

 

       而对于其它具有横切性质的服务,JavaEE规范依然显得力不从心。 

       为了弥补缺乏AOP支持的不足,EJB3提供了拦截器支持。

               本质是轻量级AOP实现,作用于AOP如出一辙

               将多个业务方法中通用逻辑从业务方法中抽离出来,放在拦截中实现,实现代码复用。

 

二.EJB3的拦截器和Spring的AOP对比

(一)不同点

       Spring的AOP实现提供了@Before,@AfterReturning,@AfterThrowing,@After,@Around等大量的Annotation,用于定义功能丰富增强处理。

       而EJB提供的拦截器机制只能算是一种轻量级的AOP实现,功能比较有限。 

(二)相同点

       均使用@AroundInvoke修饰拦截方法,方法中定义的就是分布于多个模块中,具有横切性质的通用处理代码。

 

三.使用方法

(一)定义一个拦截器

       首先定义一个拦截器类,并用@AroundInvoke修饰其中的方法,这个方法将会在SessionBean的多个方法被调用时“切入”。 

 

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import javax.interceptor.AroundInvoke;  
  2. import javax.interceptor.InvocationContext;  
  3.   
  4. public class MyInterceptor {  
  5.   
  6.     @AroundInvoke  
  7.     public Object log(InvocationContext ctx) throws Exception {  
  8.         long start=System.currentTimeMillis();  
  9.         System.out.println("----拦截器运行开始----");  
  10.         try {  
  11.             Object rvt = ctx.proceed();  
  12.             return rvt;  
  13.         } catch (Exception e) {  
  14.             System.out.println("----拦截器运行出错----");  
  15.             throw e;  
  16.         } finally {  
  17.             long time = System.currentTimeMillis() - start;  
  18.             System.out.println("----拦截器运行结束----");  
  19.             System.out.println("拦截器运行用时:" + time + "ms");  
  20.         }  
  21.   
  22.     }  
  23. }  

 

        可以看出,这个拦截器不需要实现任何接口,或继承什么基类,只要用@AroundInvoke Annotation标记该拦截器类的方法就可以。

       需要指出的是,@AroundInvoke修饰的方法必须满足如下格式:

                public Object  ****(InvocatonContext   cxt)   throws Exception

        形参InvocatonContext  对象中,包含了被调用方法的详细信息,如:

                1.Map<String,Object> getContextData():返回一个Map对象,该Map对象里封装了本次调用或生命周期回调相关上下文信息。

                2.Method getMethod():获取被拦截的方法

                3.Object[] getParameter();获取被拦截的业务方法的实际参数。

                4.Object getRarget();获取被拦截的Session Bean实例

                5.Object proceed():调用InvocationContext的该方法时,就是回调拦截方法,执行被拦截方法。

                6.void setParameters(Object[] params):修改被拦截的业务方法的实际参数

(二)定义被拦截对象

1.定义SessionBean业务接口并声明3个方法

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import javax.ejb.Remote;  
  2.   
  3. @Remote  
  4. public interface HelloWorldBean {  
  5.       
  6.     String hello1(String name);  
  7.   
  8.     void hello2();  
  9.   
  10.     void exclude();  
  11.   
  12. }  


         接口中无需使用任何Annotation

       只要在Bean实现类中使用@Interceptors来修饰即可

2.定义Bean实现类,并用@Interceptors修饰

        @Interceptors是EJB3为依赖注入提供的Annotation ,用于修饰Bean类或业务方法,使用时需要用value属性指明拦截器类的类名。

              若修饰某个Bean实现类,则对类中的所有方法均起作用

              若修饰某个Bean实现类中的方法,则只对标记的方法起作用。

               若用@ExcludeClassInterceptors修饰Bean内的某个业务上,则表示拦截器对该标记方法不起作用

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import javax.ejb.Stateless;  
  2. import javax.interceptor.AroundInvoke;  
  3. import javax.interceptor.Interceptors;  
  4. import javax.interceptor.InvocationContext;  
  5.   
  6. @Stateless(mappedName = "HelloWorldBeanImpl")  
  7. @Interceptors(MyInterceptor.class)  
  8. public class HelloWorldBeanImpl implements HelloWorldBean {  
  9.     public String hello1(String name) {  
  10.         System.out.println("我是被拦截器拦击的方法:hello1");  
  11.     }  
  12.   
  13.     public void hello2() {  
  14.         System.out.println("我是被拦截器拦截的方法:hello2");  
  15.     }  
  16.   
  17.     public void exclude() {  
  18.         System.out.println("我是被拦截器排除在外的方法:exclude");  
  19.     }  
  20.   
  21. }  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值