代理模式
我们在开发的过程经常会会遇到一个接口在执行某个方法需要进行增强操作,例如:在方法执行之前进行一些准备工作,在方法执行之后再进行一些通知的增强操作。
这种情形下我们就可以使用代理模式来进行开发,代理模式就是使用代理类来对目标类的某些方法进行代理。
有以下几种代理模式:
1:静态代理 2:动态代理
首先,我们来看看静态代理,静态代理的主要实现方式就是通过组合的方式,在代理类中引入被代理的类,然后通过重写接口的方法实现被代理类方法的增强。
核心代码:
1:代理类 和 被代理类需要实现同一个接口,或者继承同一个类
2:代理类中引用被代理来
3:代理类中重写被代理类需要增强的方法
下面以明星和代理人的关系来说明静态代理:明星开演唱会,明星 负责唱歌, 代理人需要 准备后前期和后期工作;
1:共同的接口
// 接口 interface IStar { void sing(); }
2:真实的对象,需要实现这个接口:
// 真实对象 class LDHStar implements IStar { @Override public void sing() { System.out.println("刘德华唱歌"); } }
3:代理对象,需要对真实对象有控制权,通过引用来实现增强操作
class ProxyManger implements IStar { // 真实对象的引用 private IStar star; public ProxyManger() { super(); } public ProxyManger(IStar star) { super(); this.star = star; } @Override public void sing() { System.out.println("唱歌前准备"); star.sing(); System.out.println("善后工作"); } } class Test{ public static void main(String[] args) { // 创建明星对象 IStar ldh = new LDHStar(); ProxyManger proxy = new ProxyManger(ldh); proxy.sing(); } }
其实静态代理就是通过依赖引用的方式来实现真实对象的增强操作。在实际开发中会经常通过组合引用的方式来实现多个类的逻辑功能,其实用的就是静态的模式。
下面讲讲动态代理,动态代理也称作jdk 动态代理,是一种接口代理,是在程序运行时,JVM才为被代理对象生成代理对象。因为是针对接口生成代理对象的,所以
被代理的对象需要实现接口。
以下是JDK 动态代理的代码示例:
1:被代理类需要实现的接口
public interface MySubjectIntf { void needProxy(); }
2:被代理目标类,实现需要实现接口
public class MySubject implements MySubjectIntf{ //需要被代理的方法 @Override public void needProxy(){ System.out.println("这是一个需要被代理的方法!!"); } }
3:自定义实现 InvocationHandler 接口的类,这个是JDK动态代理的的固定写法。
public class MyInvocationHandler implements InvocationHandler{ // 维护需要被代理的目标类 private MySubject subject; public MyInvocationHandler(Object subject){ this.subject=(MySubject)subject; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //增强前 System.out.println("------before------"); // 执行目前方法 Object invoke = method.invoke(subject, args); // 增强后 System.out.println("------before------"); return invoke; } // 获取代理对象 public Object getProxy(){ return Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), subject.getClass().getInterfaces(),this); } }
JDK动态带的流程比较固定,基本上以上的代码就是固定的写法,通过 Proxy.newProxyInstance() 的方式生成代理对象。目标类需要实现接口,主要是生成代理类是通过目标类的
接口,通过反射的方式生成代理类。
核心类 InvocationHandler;