• ,java反射机制实现拦截器


    实现一个拦截器必须要实现一下几个类:
    1 目标类接口:目标类要实现的接口。
    package com.lanvis.reflect;
    public interface ITarget {
        public void doSthing();
        public void doOthing();
    }
    2 目标类:目标类是要被拦截的类。它实现了目标类接口。
    package com.lanvis.reflect;
    public class Target implements ITarget {
        public void doOthing() {
            System.out.println("doOthing");
        }
        public void doSthing() {
            System.out.println("doSthing");
        }
    }
    拦截器类:目标类中的方法被拦截之后,执行拦截器中的方法。
    package com.lanvis.reflect;
    public class Interceptor {
        public void before(){
            System.out.println("before");
        }
        public void after(){
            System.out.println("after");
        }
    }
    4 处理器类:正是处理器把拦截器和目标类耦合在一起。
    package com.lanvis.reflect;
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class MyHandler implements InvocationHandler{
        private Object object;
        private Interceptor interceptor=new Interceptor();
        public void setObject(Object object) {
            this.object = object;
        }
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object result=null;    
            interceptor.before();
            result=method.invoke(object, args);
            interceptor.after();
            return result;
        }
    }
    5 代理类:程序执行时真正执行的是代理类,代理类是实现了拦截器的流程的类。
    package com.lanvis.reflect;
    import java.lang.reflect.Proxy;
    public class MyProxy {
        public Object getProxy(Object object) {
            MyHandler myHandler = new MyHandler();
            myHandler.setObject(object);
            return Proxy.newProxyInstance(object.getClass().getClassLoader(),
                    object.getClass().getInterfaces(), myHandler);
        }
    }
    6 测试类:用来测试拦截器成功与否。
    package com.lanvis.reflect;
    public class Test {
        public static void main(String[] args){
            ITarget target=new Target();
            MyProxy myProxy=new MyProxy();
            ITarget proxy=(ITarget)myProxy.getProxy(target);
            proxy.doSthing();
            proxy.doOthing();
        }
    }
     
    注:认真学习java反射机制,这很重要。
     
     
    总结:
    JAVA动态代理,调用的是代理类,所以这就需要代理类知道原始目标类有哪些接口啊,这样才能不会调错哈,原始信息都有。
    那怎么才能让代理类知道原始目标类有哪些接口呢?这就需要在创建代理类的时候指定原始目标类的class信息,包括有原始目标class.getInterfaces(),原始ClassLoader,当做参数传进去代理类的构造函数中啊,即
    Proxy.newProxyInstance(object.getClass().getClassLoader(),
                    object.getClass().getInterfaces(), myHandler);
    那么代理类内部怎么实现调用原始目标类呢?通过invocationHandler接口啊,这个接口通过proxy代理类传进来的method实例,(proxy有原始目标类的所有method实例),然后用method实例反射功能去调用原始目标类的自己的方法,传入参数也会跟着proxy的传入参数传进来这个invoke参数里面。所以这就有了最核心的代理类调用原始目标类,代理类实现了调用原始目标类。
     
    那下一步是怎么实现前后拦截的呢?
    :我们都知道是invoke()接口实现的调用原始目标类,最核心的method.invoke()前后就可以啊,前后手动加上要添加的方法。就可以了嘛。
    如:
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            Object result=null;    
            interceptor.before();
            result=method.invoke(object, args);
            interceptor.after();
            return result;
        }
    就实现了利用JDK动态代理AOP面向切面编程,
     
    3.那怎么实现只针对某个接口里的某个方法拦截,而不是针对接口里所有方法都拦截呢?
    :只需要在调用invoke方法里,method调用前,加个if判断嘛,根据method,getName().equal(“具体方法”)
     
     
  • 相关阅读:
    HDU 2112 HDU Today
    HDU 1869 六度分离
    HDU 3790 最短路径问题
    HDU2066 一个人的旅行
    HDU1596 find the safest road(最短路)
    HDU 1254 推箱子(双重bfs)
    HDU 1429 胜利大逃亡(续) (bfs+状态压缩)
    HDU 1045 Fire Net
    数据结构之单链表头插法,尾插法
    Java--会移动、反弹的球
  • 原文地址:https://www.cnblogs.com/panxuejun/p/7719413.html
Copyright © 2020-2023  润新知