拦截器,本质上是由反射(动态代理)完成的。
手写一个简单的拦截器来了解拦截器工作的流程。
拦截器执行的步骤大体如下。
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();
}
}
测试结果