拦截器就是一个类,其实现的原理是java的动态代理。 在此,首先了解一下java的代理模式。代理模式就是指一个人或一个机构代替另一个人或机构去做一些事情。例如,书店就是出版社的一个代理,而要做的事情就是代理。 为什么会需要代理模式? 一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。 在代理模式中有3个重要的角色: 1.抽象主题角色:真实主题与代理主题的共同接口。 2.真实主题角色:定义了代理角色所代表的真实对象 3.代理主题角色:含有对真实主题角色的引用,代理角色通常是在客户端调用真实对象的方法之前或之后执行某些操作,而不是单纯的返回真是对象。 在上面这个例子中,抽象主题角色就是卖书,真实主题角色是出版社,代理主题角色是书店。 使用代理模式的基本步骤如下 1.创建一个抽象类,这个抽象类代表着抽象主题角色。 在此例中,创建抽象类Subject,其有个抽象方法,sailBook,具体实现如下: package cn.tshining.proxy; public abstract class Subject { 2.生成真实主题角色。这个类将继承抽象类 package cn.tshining.proxy; public class RealSubject extends Subject { @Override 3.创建代理主题角色,这个类也继承抽象类 package cn.tshining.proxy; public class ProxySubject extends Subject { private RealSubject realSubject; @Override doDazhe(); if (realSubject == null) { realSubject.sailBook(); give(); public void doDazhe() { public void give() { package cn.tshining.proxy; public class Client { public static void main(String[] args) { 运行后结果显示如下: 打折 这只是一个简单的示例,演示了代理模式的工作原理。 但是在代理模式中,客户端每次调用真实主题角色对象的方法时,就要生成一个真实主题角色对象,还有一个代理主题角色对象,这会造成资源的极大浪费。 所以JDK中提供了一个Proxy类来实现动态代理。动态代理是通过Proxy类动态地生成代理主题角色。 现在用动态代理来重写上面的例子: 实现动态代理的步骤如下: 1.创建抽象主题角色。但是这里不再是一个抽象类,而是一个接口,因为JDK的动态代理只能对实现了接口的实例来生成动态代理。 package cn.tshining.dynamicproxy; public interface Subject { 2. 创建真实主题角色。该类实现了上面的接口。 package cn.tshining.dynamicproxy; public class RealSubject implements Subject { @Override 3.新建处理类,该类实现invocationHandler接口,它可以动态调用目标对象中的方法,在该类代码中同样包含真实主题角色引用。 package cn.tshining.dynamicproxy; import java.lang.reflect.InvocationHandler; public class MyHandler implements InvocationHandler { private Object realSubject; @Override } 4.新建一个Client类用来测试,在该类中新建一个真实主题对象实例,并将其设置到代理的处理类中,通过Proxy类的newProxyInstance方法来穿件动态代理实例。 package cn.tshining.dynamicproxy; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { MyHandler mh = new MyHandler(); mh.setRealSubject(realSubject); Subject proxySubject = (Subject) Proxy.newProxyInstance( 在这个类中用到了Proxy的newProxyInstance方法: public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h) 运行该示例,结果为: 打折 在动态代理中,代理对象是系统动态产生的,动态代理必须依靠借口来实现。 |
|