zoukankan      html  css  js  c++  java
  • EJB>拦截器(Interceptor)

    拦截器(Interceptor)
    拦截器可以监听程序的一个或所有方法。拦截器对方法调用流提供了细粒度控制。可以在无状态会话bean、有状态会话bean 和消息驱动bean 上使用它们。拦截器可以是同一bean 类中的方法或是一个外部类。
    下面介绍如何在Session Bean 类中使用外部拦截器类。
    HelloChinaBean.java
    package com.foshanshop.ejb3.impl;
    
    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 (HelloChinaRemote.class)
    @Local(HelloChina.class)
    @Interceptors(HelloInterceptor.class) 
    public class HelloChinaBean implements HelloChina,HelloChinaRemote {
    
        public String SayHello(String name) {
            return name +"说:你好!中国.";
        }
    
        public String Myname() {        
            return "我是佛山人";
        }
    }

    如果你只需对某一方法进行拦截,你可以在方法上面定义拦截器,如:

    public class HelloChinaBean implements HelloChina,HelloChinaRemote {
    @Interceptors(HelloInterceptor.class)
    public String SayHello(String name) {
    return name +"说:你好!中国.";
    }
    }

    HelloInterceptor

    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
    XXX 代表方法名可以任意。javax.interceptor.InvocationContext 封装了客户端所调用业务方法的一些信息。下面是
    InvocationContext 的定义:
    package javax.interceptor;
    public interface InvocationContext {
    public Object getTarget( );
    public Method getMethod( );
    public Object[] getParameters( );
    public void setParameters(Object[] newArgs);
    public java.util.Map<String, Object> getContextData( );
    public Object proceed( ) throws Exception;
    }
    getTarget( ) 指向被调用的bean 实例
    getMethod( ) 指向被拦截的业务方法
    getParameters( ) 获取被拦截业务方法的参数
    setParameters() 设置被拦截业务方法的参数
    getContextData( ) 方法返回一个Map 对象,它在整个方法调用期间都可以被访问到。位于同一方法调用内的不同
    拦截器之间可以利用它来传递上下文相关的数据。
    在HelloInterceptor 代码中,我们调用了ctx.proceed()方法。如果还有其它拦截器未执行,ctx.proceed()方法内部会
    调用后面拦截器的@AroundInvoke 方法,直到后面的拦截器全部执行结束,EJB 容器才会执行被拦截的业务方法。
    ctx.proceed()方法必须在拦截器代码中被调用,否则被拦截的业务方法就根本不会被执行。另外如果我们想在被拦
    截的业务方法执行结束后再执行一些自定义代码,我们可以在ctx.proceed()执行后方法返回前加入自己的代码,

    如:
    @AroundInvoke
    public Object log(InvocationContext ctx) throws Exception {
    System.out.println("*** HelloInterceptor intercepting");
    long start = System.currentTimeMillis();
    try{
    Object o = ctx.proceed();
    //这里加入你需要执行的代码
    return o;
    
    }catch (Exception e) {
    throw e;
    }finally {
    long time = System.currentTimeMillis() - start;
    System.out.println("用时:"+ time + "ms");
    }
    }

    将Session Bean 中的一个或多个方法定义为拦截器,只需一个@AroundInvoke 注释就指定了要用作拦截器的方法。

    package com.foshanshop.ejb3.impl;
    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.AroundInvoke;
    import javax.interceptor.InvocationContext;
    @Stateless
    @Remote ({HelloChinaRemote.class})
    @Local(HelloChina.class)
    public class HelloChinaBean implements HelloChina,HelloChinaRemote {
    public String SayHello(String name) {
    return name +"说:你好!中国.";
    }
    public String Myname() {
    return "我是佛山人";
    }
    @AroundInvoke
    public Object log(InvocationContext ctx) throws Exception {
    try{
    if (ctx.getMethod().getName().equals("SayHello")){
    System.out.println("*** HelloChinaBean.SayHello() 已经被调用! *** " );
    }
    if (ctx.getMethod().getName().equals("Myname")){
    System.out.println("*** HelloChinaBean.Myname() 已经被调用! *** " );
    }
    return ctx.proceed();
    }catch (Exception e) {
    throw e;
    }
    }
    

  • 相关阅读:
    CF500F New Year Shopping [线段树分治,背包]
    P5344 【XR-1】逛森林[倍增优化建图,zkw线段树优化spfa]
    CF452F Permutation [哈希,树状数组]
    [NOI Online #2 提高组]子序列问题
    牛客挑战赛39题解
    #6036. 「雅礼集训 2017 Day4」编码 [前缀优化2sat]
    CF1156E Special Segments of Permutation [分治,set]
    #6198. 谢特 [后缀自动机,01trie合并,启发式合并]
    P4246 [SHOI2008]堵塞的交通 [动态图连通性]
    CF1096G Lucky Tickets [NTT,多项式快速幂]
  • 原文地址:https://www.cnblogs.com/xqzt/p/5637406.html
Copyright © 2011-2022 走看看