写这篇主要是由于自己一直忘记,动态代理在许多地方都是常用,特别是在接触一框架,都有动态代理的影子。
动代理模式是什么,简单来说代理就是在你要执行的核心内容前后进行一些修饰。
应用到程序中:即将核心功能与辅助功能(事务、日志、性能监控代码)分离,达到核心业务功能更纯粹、辅助业务功能可复用。
一、静态代理
有动态代理肯定就有静态,静态与动态最直接区别,静态是死的比较容易理解,动态是灵活性比较高,理解起来还需要结合更多实战经验
下面用一张图来解释这个流程:静态代理就不在阐述了【相信你自己也会写的出来】
简单理解:
代理类 = 实现原始类相同接口 + 添加辅助功能 + 调用原始类的业务方法。
流程理解:
例如:现在房东有一个房间要出租,它就会找到中介进行房屋出租,中介发布房子信息,带租户看房子,租户满意就跟房东交房租,签合同。
中介代理了房屋生成的代理类流程:发布信息 ==》 租户看房 ==》房东签合同、收房租===》完成
-
代理类数量过多,不利于项目的管理。
-
多个代理类的辅助功能代码冗余,修改时,维护性差。
由于静态代理的种种约束,很多场合不在适用,就需要动态代理来弥补不足之处。
动态代理的思维方式跟静态代理是一致的,找别人来对你要执行的事情进行封装,修饰。
二、JDK动态代理【基于接口】
TargetInterface:目标对象接口
Target:目标对象【需被代理对象】
Advice:增强方法【对目标对象进行增强处理 相当于中介的发布房子、带租客看房】
TextJDk:代理类【生成最终代理结果】
TargetInterface:
public interface TargetInterface { void save(); }
Target【实现类】:
public class Target implements TargetInterface { @Override public void save() { System.out.println("save running....."); } }
Advice【增强方法】:
public class Advice { public void before(){ System.out.println("前置增强..."); } public void afterReturning(){ System.out.println("后置增强..."); } }
TextJDK【代理类】
public class JDKTest { public static void main(String[] args) { Target target = new Target();//目标对象 Advice advice = new Advice();//增强方法 //接收的参数应该是目标对象父类
//Proxy.newProxyInstance 代理方法
TargetInterface proxy = (TargetInterface)Proxy.newProxyInstance(
target.getClass().getClassLoader(), //目标对象加载器 target.getClass().getInterfaces(),//目标对象相同的接口字节码对象数组 new InvocationHandler() { //实现代理流程 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { advice.before(); //前置处理 Object invoke = method.invoke(target, args); //使用反射执行目标对象方法 advice.afterReturning(); //后置处理 return invoke; //返回目标对象结果 } }); proxy.save(); //运行结果 } }
//看注释,就不在阐述了==》之所以用目标对象接口来接收是因为 :目标对象相当于代理类返回值的兄弟类【同等级】,会异常
==》所以只能用目标对象的上一级来接收,才能实现代理
运行结果:
三、cglib动态代理基于父类
Target:目标对象【需被代理对象】
Advice:增强方法【对目标对象进行增强处理 相当于中介的发布房子、带租客看房】
TextCglib:代理类【生成最终代理结果】
基于父类的代理肯定没有接口,其他与JDK动态一致,不一致的是实现代理的方式,流程是一致
//目标对象
public class Target { public void save() { System.out.println("save running................"); } }
//增强方法
public class Advice { public static void before(){ System.out.println("前置增强。。。。"); } public static void after(){ System.out.println("后置增强。。。。"); } }
//实现代理
public class TextCglib{ public static void main(String[] args) { Target target = new Target(); //基于cglib返回动态代理对象 //创建增强器 Enhancer enhancer = new Enhancer(); //设置父类(目标),没有父类则就是当前类 enhancer.setSuperclass(Target.class); //设置回调[MethodInterceptor:Callback子接口] enhancer.setCallback(new MethodInterceptor() {//代理方法 @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { //实现代理流程 Advice.before(); Object invoke = method.invoke(target,args);//使用反射执行目标方法 Advice.after(); return invoke; //返回代理结果 } }); //生成代理对象 Target proxy = (Target) enhancer.create(); proxy.save(); } }