EJB中的interceptor~~

可以说拦截器是AOP在EJB world里面的实现,拦截器可以用于SesstionBean和Message Driven

Bean。拦截器可以用Descriptor

file或者annotation来实现,但是基本上我们都是用annotation来实现。拦截器可以用来
      

看下@Interceptors的J2EE文档,发现它的内容如下:

    @Target(value={TYPE,METHOD})
@Retention(value=RUNTIME)

public @interface Interceptors{

public Class[] value();

}

      

@Interceptors可以用在类级别,也可以用在方法上,用在类级别上,就代表整个类的所有方法在被调用的时候都会让拦截器的方法被调用,而用在method上,则只有该方法的调用之前会让拦截器的方法被调用。

      

举个例子,HelloWorldBean实现IHelloWorld的业务接口,有两个方法SayHello1()和SayHello2(),拦截器打印出哪个方法被调用。
      

@Interceptors(HelloInterceptor.class)
       @Stateless
       public

class HelloWorldBean implements IHelloWorld{
                public void

SayHello1(){
                         …….
               

}
                public void SayHello2(){
                        

……
                }
       }

       public class

HelloInterceptor{
               

//含有AroundInvoke注解的方法就是拦截器方法
                @AroundInvoke
               

public Object getMethod(InvocationContext invocationContext) throws

Exception{
                         System.out.println(“method “+

invocationContext.getMethod().getName() +”

invoked”);
                          return

invocationContext.proceed();
                }
       }

     

上面这个例子是将@Interceptors用于类级别的,用于方法级别的时候就对那个特定的方法的调用进行拦截。
       
      

其实还可以定义default Interceptor,它可以用来拦截所有bean的所有方法。如下:
  

<assembly-descriptor>
    <interceptor-binding>
         

<ejb-name>*</ejb-name>
          <interceptor-class>

              ejb.impl.DefaultInterceptor
       

</interceptor-class>
    </interceptor-binding>

</assembly-descriptor>  
  

现在问题来了,一个方法被调用的时候,可能会有多个拦截器发生作用(默认拦截器、类级别的和方法级别的),他们的调用顺序是什么的,答案是从大的范围到小的范围。即default

interceptor->class interceptor->method interceptor。

    
     

对于InvocationContext这个接口,
public interface InvocationContext {
    public

Object getTarget();
    public Method getMethod();
    public Object[]

getParameters();
    public void setParameters(Object[]);
    public

java.util.Map<String,Object> getContextData();
    public Object

proceed() throws Exception;
}

   有几个方法需要说明下:
   

InvocationContext.proceed()
method: This tells the
container that

it should proceed to the next Interceptor in the execution chain or call the

intercepted business method. On the other hand, not calling the proceed

method will bring
processing to a halt and avoid the business method (and

any other Interceptor down the
execution chain) from being called.

InvocationContext.getContextData()

method:返回的的这个Map可以在整个的interceptor

chain中共享,这意味着可以在同一个bean的多个interceptor中共享信息。

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s