• 利用JDK动态代理机制实现简单拦截器


    利用JDK动态代理机制实现简单的多层拦截器

    首先JDK动态代理是基于接口实现的,所以我们先定义一个接口

    public interface Executer {
        public Object execute(String param);
    }

    然后我们写一个类来实现该接口,我们将该类成为目标类。接下来我们将要对execute方法进行拦截!

    public class SampleExecuter implements Executer {
    
        public Object execute(String param) {
            System.out.println("SampleExecuter.execute()");
            return "SampleExecuter.execute()" + param;
        }
    
    }

    我们需要定义拦截器接口 Interceptor

    public interface Interceptor {
    
        public Object intercept(Invocation invocation) throws Throwable;
        
    }

    定义类 Invocation 该类负责调用我们目标对象的方法

    public class Invocation {
    
        private Object target;
        
        private Method method;
        
        private Object[] args;
    
        public Invocation(Object target, Method method, Object[] args) {
            this.target = target;
            this.method = method;
            this.args = args;
        }
        
        public Object getTarget() {
            return target;
        }
    
        public void setTarget(Object target) {
            this.target = target;
        }
    
        public Method getMethod() {
            return method;
        }
    
        public void setMethod(Method method) {
            this.method = method;
        }
    
        public Object[] getArgs() {
            return args;
        }
    
        public void setArgs(Object[] args) {
            this.args = args;
        }
        
        public Object proceed() throws IllegalAccessException, InvocationTargetException {
            return method.invoke(target, args);
        }
    }

    代理类的实现

    public class PlugIn implements InvocationHandler {
    
        private Object target;
        private Interceptor interceptor;
        
        public PlugIn(Object target, Interceptor interceptor) {
            this.target = target;
            this.interceptor = interceptor;
        }
        
        public Object invoke(Object proxy, Method method, Object[] args)
                throws Throwable {
            return interceptor.intercept(new Invocation(target, method, args));
        }
        
        /**
         * 通过JDK动态代理Proxy.newProxyInstance返回代理对象
         * @param target 目标对象
         * @param interceptor 拦截器对象
         * @return 代理对象
         */
        public static Object warp(Object target, Interceptor interceptor) {
            Class<?> type = target.getClass();
            return Proxy.newProxyInstance(type.getClassLoader(), type.getInterfaces(),
                                            new PlugIn(target, interceptor));
        }
        
    }

    InterceptorChain 用来注册拦截器,并将拦截器与目标对象结合生成代理对象

    public class InterceptorChain {
    
        private List<Interceptor> interceptors = new ArrayList<Interceptor>();
        
        public void addInterceptor(Interceptor interceptor) {
            interceptors.add(interceptor);
        }
        
        public Object pluginAll(Object target) {
            for (Interceptor interceptor : interceptors) {
                target = PlugIn.warp(target, interceptor);
            }
            return target;
        }
    }

    最后写俩个拦截器来测试我们的程序吧

    public class IntOne implements Interceptor {
    
        public Object intercept(Invocation invocation) throws IllegalAccessException, InvocationTargetException {
            System.out.println("IntOne.intercept()-begin");
            Object result = invocation.proceed();
            System.out.println("IntOne.intercept()-end");
            return result;
        }
    
    }
    public class IntTwo implements Interceptor {
    
        public Object intercept(Invocation invocation) throws IllegalAccessException, InvocationTargetException {
            System.out.println("IntTwo.intercept()-begin");
            Object result = invocation.proceed();
            System.out.println("IntTwo.intercept()-end");
            return result;
        }
    
    }
    public class Demo {
    
        public static void main(String[] args) {
            SampleExecuter target = new SampleExecuter();
            InterceptorChain chain = new InterceptorChain();
            
            chain.addInterceptor(new IntOne());
            chain.addInterceptor(new IntTwo());
            
            Executer executer = (Executer) chain.pluginAll(target);
            Object result = executer.execute("params");
            System.out.println(result);
        }
    
    }

    执行结果

    IntTwo.intercept()-begin
    IntOne.intercept()-begin
    SampleExecuter.execute()
    IntOne.intercept()-end
    IntTwo.intercept()-end
    SampleExecuter.execute()params

  • 相关阅读:
    MySQL中的while循环和repeat循环的区别
    Python 基础语法_Python脚本文件结构
    Python 基础语法_Python脚本文件结构
    MySQL存储过程和函数的区别
    第四章 语句和声明
    haproxy 4层和7层负载
    献血是件很赞的事——北漂18年(26)
    JavaScript字符串数值比较问题
    MySQL查看所有可用的字符集
    MySQL获取表格信息
  • 原文地址:https://www.cnblogs.com/daxin/p/3351824.html
Copyright © 2020-2023  润新知