关于拦截器的一点总结

来源:互联网 发布:vivo手机怎么改mac地址 编辑:程序博客网 时间:2024/06/03 14:10

拦截器,本质上是由反射(动态代理)完成的。
手写一个简单的拦截器来了解拦截器工作的流程。
拦截器执行的步骤大体如下。
1:声明拦截器要拦截的目标,以及拦截器。
2:将拦截器与目标绑定。生成代理类。
3:执行代理类的invoke方法。
4:在代理类中声明拦截器的处理器(将被代理对象,被代理对象的方法,参数传入)
5:执行拦截器的方法并将拦截器的处理器作为参数传入拦截器。
6:执行处理器的方法。
声明拦截目标接口及实现类。声明拦截器,并且声明bind及普通执行方法,并为普通执行方法绑定处理器。

package target;public interface Target {    public void sayHello();}
package target;public class TargetImpl implements Target { @Override public void sayHello() {  System.out.println("hello, world fuck your asshole!"); }}

声明处理器,并声明处理器执行方法,方法中是执行反射处来的被代理对象真正执行的方法。

package invocation;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class Invocation {    private Object object;    private Method method;    private Object[] args;    public Invocation(Object object,Method method,Object[] args){        this.object=object;        this.method=method;        this.args=args;    }    public Object doWork() throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{        return method.invoke(object, args);    }}

声明拦截器

package interceptor;import java.lang.reflect.InvocationTargetException;import invocation.Invocation;public interface Interceptor {    public Object bind(Interceptor this,Object object);    public Object dosomething(Invocation invocation) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException;}

声明代理类并在invoke方法中执行拦截器方法。

import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import interceptor.Interceptor;import invocation.Invocation;public class ProxyTarget implements InvocationHandler{    private Object object;    private Interceptor interceptor;    public ProxyTarget(Object object,Interceptor interceptor){        this.object=object;        this.interceptor=interceptor;    }    public static Object bind(Object object,Interceptor interceptor){        return Proxy.newProxyInstance(object.getClass().getClassLoader(), object.getClass().getInterfaces(), new ProxyTarget(object,interceptor));    }    @Override    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {        Invocation invocation = new Invocation(object,method,args);        return interceptor.dosomething(invocation);    }}

声明拦截器的实现类,如Log,当然也可以加上比如事物之类的。

package interceptor;import java.lang.reflect.InvocationTargetException;import invocation.Invocation;import target.ProxyTarget;public class LogInterceptor implements Interceptor {    @Override    public Object bind(Object object) {        return ProxyTarget.bind(object, this);    }    @Override    public Object dosomething(Invocation invocation) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {        System.out.println("do some Log");        return invocation.doWork();    }}

测试

package test;import org.junit.Test;import interceptor.Interceptor;import interceptor.LogInterceptor;import target.Target;import target.TargetImpl;public class test {    @Test    public void test(){        Interceptor i = new LogInterceptor();        Target target = new TargetImpl();        target = (Target) i.bind(target);        target.sayHello();    }}

测试结果
这里写图片描述

原创粉丝点击