拦截器在在流行的开源框架中很常见,依赖的技术就是Java的动态代理。
理解拦截器的核心原理对理解这些开源框架的体系结构至关重要。
下面以一个简单的模型的来说明拦截器的实现的一般方法。
模型分为以下模块:
业务组件:是被代理和被拦截的对象。
代理处理器:实现了InvocationHandler接口的一个对象
代理对象:Proxy对象。
拦截器:普通的JavaBean,在调用业务方法的之前或者之后会自动拦截并执行自己的一些方法。
客户端:执行业务处理的入口。
以下是模型的实现
一、业务组件:分为业务接口和业务类
/** * Created by IntelliJ IDEA. * User: leizhimin * Date: 2008-3-20 23:32:06 * Company: LavaSoft(http://lavasoft.blog.51cto.com/) * 业务组件接口 */ public interface BusinessInterface { public void doSomething(); } /** * Created by IntelliJ IDEA. * User: leizhimin * Date: 2008-3-20 23:31:12 * Company: LavaSoft(http://lavasoft.blog.51cto.com/) * 业务组件 */ public class BusinessClass implements BusinessInterface{ public void doSomething() { System.out.println("业务组件BusinessClass方法调用:doSomething()"); } }
二、代理处理器:包含了业务对象绑定动态代理类的处理,并实现了InvocationHandler接口的invoke方法。
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Created by IntelliJ IDEA. * User: leizhimin * Date: 2008-3-20 23:24:10 * Company: LavaSoft(http://lavasoft.blog.51cto.com/) * 动态代理处理器工具 */ public class DynamicProxyHandler implements InvocationHandler { private Object business; //被代理对象 private InterceptorClass interceptor = new InterceptorClass(); //拦截器 /** * 动态生成一个代理类对象,并绑定被代理类和代理处理器 * * @param business * @return 代理类对象 */ public Object bind(Object business) { this.business = business; return Proxy.newProxyInstance( //被代理类的ClassLoader business.getClass().getClassLoader(), //要被代理的接口,本方法返回对象会自动声称实现了这些接口 business.getClass().getInterfaces(), //代理处理器对象 this); } /** * 代理要调用的方法,并在方法调用前后调用连接器的方法. * * @param proxy 代理类对象 * @param method 被代理的接口方法 * @param args 被代理接口方法的参数 * @return 方法调用返回的结果 * @throws Throwable */ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; interceptor.before(); result=method.invoke(business,args); interceptor.after(); return null; //To change body of implemented methods use File | Settings | File Templates. } }
三、拦截器:普通的JavaBean,在调用业务方法的之前或者之后会自动拦截并执行自己的一些方法。
/** * Created by IntelliJ IDEA. * User: leizhimin * Date: 2008-3-20 23:26:31 * Company: LavaSoft(http://lavasoft.blog.51cto.com/) * 拦截器 */ public class InterceptorClass { public void before(){ System.out.println("拦截器InterceptorClass方法调用:before()!"); } public void after(){ System.out.println("拦截器InterceptorClass方法调用:after()!"); } }
四、模拟客户端:执行业务处理的入口。
/** * Created by IntelliJ IDEA. * User: leizhimin * Date: 2008-3-21 0:32:55 * Company: LavaSoft(http://lavasoft.blog.51cto.com/) * 客户端 */ public class Client { public static void main(String args[]) { DynamicProxyHandler handler = new DynamicProxyHandler(); BusinessInterface business = new BusinessClass(); BusinessInterface businessProxy = (BusinessInterface) handler.bind(business); businessProxy.doSomething(); } }