利用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