zoukankan      html  css  js  c++  java
  • 拦截器(由JDK动态代理实现的拦截器)

    要实现拦截器,首先我们需要定义几个类和接口

    package com.xiawei.reflect.interceptor;

    public interface JavaBenDao {

    public void look();
    }

    ==================================================

    package com.xiawei.reflect.interceptor;

    public class JavaBenDaoImpl implements JavaBenDao {

    @Override
    public void look() {
    System.out.println("这是真实对象的方法!");
    }

    }

    ==================================================

    这里要自定义一个拦截器的接口,并且定义了三个抽象的方法

    before(),around(),after()。这三个方法分别被用在执行反射

    方法前;取代被代理的对象时;在执行反射方法后三个节点。

    package com.xiawei.reflect.interceptor;

    import java.lang.reflect.Method;

    /**
    * 自定义拦截器的接口
    * @author Administrator
    *
    */
    public interface InterceptorDao {

    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);
    }

    ====================================================

    package com.xiawei.reflect.interceptor;

    import java.lang.reflect.Method;
    /**
    * 拦截器实现类
    * @author Administrator
    *
    */
    public class InterceptorDaoImpl implements InterceptorDao{

    @Override
    public boolean before(Object proxy, Object target, Method method, Object[] args) {
    System.out.println("在执行反射方法前执行的逻辑!");
    return true;//默认值false表示不返回代理对象的原有方法
    }

    @Override
    public void around(Object proxy, Object target, Method method, Object[] args) {
    System.out.println("取代被代理的对象的方法!");

    }

    @Override
    public void after(Object proxy, Object target, Method method, Object[] args) {
    System.out.println("在执行反射方法后执行的逻辑!");

    }

    }

    ====================================================

    这里创建一个JDK动态代理类,再在动态代理中使用拦截器

    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    /**
    * 在动态代理中使用拦截器</p>
    * 动态代理类
    * @author Administrator
    *
    */
    public class JdkInterceptorClass implements InvocationHandler {

    /**
    * 真实对象
    */
    private Object target;
    /**
    * 拦截器的全限定名
    */
    private String interceptorClass;

    public JdkInterceptorClass(Object target, String interceptorClass) {
    this.target = target;
    this.interceptorClass = interceptorClass;
    }

    //绑定委托对象,并返回一个代理站位
    public static Object bind(Object target,String interceptorClass){

    return Proxy.newProxyInstance(target.getClass().getClassLoader(),
    target.getClass().getInterfaces(), new JdkInterceptorClass(target,interceptorClass));
    }

    /**
    * 通过代理对象调用方法,首先进入invoke()
    * @param proxy 代理对象
    * @param method 被调用的方法
    * @param args 方法参数
    */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //判断,如果拦截器全限定名为空,也就是没有设置拦截器则反射原有方法(真实对象的方法)
    if(interceptorClass == null){
    return method.invoke(target, args);
    }

    //通过反射生成拦截器
    Object result = null;//定义执行以下逻辑后的返回值
    InterceptorDao interceptor =
    (InterceptorDao) Class.forName(interceptorClass).newInstance();

    //调用真实对象的方法前的方法逻辑
    if(interceptor.before(proxy, target, method, args)){
    //如果为true,则反射原有(真实)对象方法
    result = method.invoke(target, args);
    }else{
    //如果为false,执行around()方法
    interceptor.around(proxy, target, method, args);
    }
    //调用真实对象的方法后的方法逻辑
    interceptor.after(proxy, target, method, args);

    return result;
    }

    }

    =========================================================

    好了,代码完成后我们测试一下,写个测试类

    package com.xiawei.reflect.interceptor;

    public class Test {

    public static void main(String[] args) {
    //获得代理对象
    JavaBenDao proxy = (JavaBenDao) JdkInterceptorClass.bind(new JavaBenDaoImpl(),
    "com.xiawei.reflect.interceptor.InterceptorDaoImpl");
    //调用真实对象的方法
    proxy.look();

    }

    运行结果:

      在执行反射方法前执行的逻辑!
      这是真实对象的方法!
      在执行反射方法后执行的逻辑!

    可以将上面的 before()方法的返回值改为false试一下.哈哈

  • 相关阅读:
    C#防止窗口重复打开
    c#image与byte数组的转换
    物理网卡地址
    C#[WinForm]实现自动更新
    js计算散点图方程式
    js遮罩效果
    js实现四舍六入 奇进偶舍
    ajax加载表格数据
    C#创建和调用WebService详细教程
    .NET中的CTS、CLS和CLR
  • 原文地址:https://www.cnblogs.com/xiaweicn/p/8672079.html
Copyright © 2011-2022 走看看