拦截器

由于动态代理一般较难理解,所以程序设计者通常会设计一个拦截器接口共开发者使用。开发者只需要知道拦截器接口的方法、含义和作用即可。

  1. 开发者只要知道拦截器的作用就可以编写拦截器了,编写完就可以设置拦截器了,这样就可以完成任务,对开发者而言相对简单了。
  2. 设计者是精通java的开发人员,他来完成动态代理过程。
  3. 设计者只会把接口暴露给开发者使用,让动态代理过程从开发人员眼中消失。

使用JDK动态代理来实现一个拦截器逻辑。

//先定义拦截器接口

public interface Interceptor {

 

   public boolean before(Object proxy, Object target, Method method, Object[] args);

 

   public void around(Object proxy, Object target, Method method, Object[] args);

 

   public void after(Object proxy, Object target, Method method, Object[] args);

}

 

Before 方法,在真实对象前调用,当返回为true是则反射真实对象的方法,当返回为false时掌握调用around方法。

around方法:当Before返回为false时调用。

after方法: 在反射真实对象方法或者around方法执行之后,调用。

//实现拦截器接口的类

public class MyInterceptor implements Interceptor {

   @Override

   public boolean before(Object proxy, Object target, Method method, Object[] args) {

      System.err.println("反射方法前逻辑");

      return false;// 不反射被代理对象原有方法

   }

 

   @Override

   public void after(Object proxy, Object target, Method method, Object[] args) {

      System.err.println("反射方法后逻辑。");

   }

 

   @Override

   public void around(Object proxy, Object target, Method method, Object[] args) {

      System.err.println("取代了被代理对象的方法");

   }

}

//拦截器中从开发者眼中消失了的动态代理实现拦截器的过程。

public class InterceptorJdkProxy implements InvocationHandler {

 

    private Object target; //真实对象

    private String interceptorClass = null;//拦截器全限定名

   

    public InterceptorJdkProxy(Object target, String interceptorClass) {

        this.target = target;

        this.interceptorClass = interceptorClass;

    }

 

    /**

     * 绑定委托对象并返回一个【代理占位】

     *

     * @param target 真实对象

     * @return 代理对象【占位】

     */

    public static Object bind(Object target, String interceptorClass) {

        //取得代理对象   

        return Proxy.newProxyInstance(target.getClass().getClassLoader(),

                target.getClass().getInterfaces(),

                new InterceptorJdkProxy(target, interceptorClass));

    }

 

    @Override

    /**

     * 通过代理对象调用方法,首先进入这个方法.

     * @param proxy --代理对象

     * @param method --方法,被调用方法

     * @param args -- 方法的参数

     */

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        if (interceptorClass == null) {

            //没有设置拦截器则直接反射原有方法

            return method.invoke(target, args);

        }

        Object result = null;

        //通过反射生成拦截器

        Interceptor interceptor =

            (Interceptor) Class.forName(interceptorClass).newInstance();

        //调用前置方法

        if (interceptor.before(proxy, target, method, args)) {

            //反射原有对象方法

            result = method.invoke(target, args);

        } else {//返回false执行around方法

            interceptor.around(proxy, target, method, args);

        }

        //调用后置方法

        interceptor.after(proxy, target, method, args);

        return result;

    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值