spring 梳理10--代理模式 静态代理、动态代理、基于接口的动态代理----JDK动态代理 基于类的动态代理--cglib
1、代理模式回顾
代理模式,使得在IOC中实现AOP变得可能。
代理模式分为静态代理和动态代理。代理的核心功能是方法增强
(1)静态代理
静态代理角色分析
抽象角色 : 一般使用接口或者抽象类来实现
真实角色 : 被代理的角色
代理角色 : 代理真实角色 ; 代理真实角色后 , 一般会做一些附属的操作 .
客户 : 使用代理角色来进行一些操作
代码实现
写一个接口,即抽象角色
public interface Singer { /** * 歌手的统一方法 */ void sing(); }
Host . java 即真实角色
public class MaleSinger implements Singer { @Override public void sing() { System.out.println("我要唱歌了!!!"); } }
Proxy . java 即代理角色
public class Agent implements Singer { private Singer singer; /** * 经纪人必须代理一个歌手 * @param singer */ Agent(Singer singer){ this.singer = singer; } @Override public void sing() { System.out.println("经纪人要把把关,看看这个演出合适不合适!"); singer.sing(); System.out.println("歌手唱完歌,经纪人去收钱!"); } }
Client . java 即客户
public class Client { public static void main(String[] args) { Singer luhan = new MaleSinger(); Agent zhangsan = new Agent(luhan); zhangsan.sing(); } }
分析:在这个过程中,你直接接触的就是鹿晗的经济人,经纪人在鹿晗演出的前后跑前跑后发挥了巨大的作用。
优点
鹿晗还是鹿晗,没有必要为了一下前置后置工作改变鹿晗这个类
公共的统一问题交给代理处理,更加符合开闭原则,单一原则
公共业务进行扩展或变更时,可以更加方便
缺点 :
每个类都写个代理,麻烦
(2)动态代理
动态代理的角色和静态代理的一样 .
动态代理的代理类是动态生成的 . 静态代理的代理类是我们提前写好的
动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
- 基于接口的动态代理----JDK动态代理
- 基于类的动态代理--cglib
- 现在用的比较多的是 javasist 来生成动态代理 . 百度一下javasist
- 我们这里使用JDK的原生代码来实现,其余的道理都是一样的!
JDK的动态代理需要了解两个类 InvocationHandler 和 Proxy(打开JDK帮助文档看看)
【InvocationHandler:调用处理程序】
【Proxy : 代理】
代码实现
抽象角色和真实角色和之前的一样! 还是歌星和男歌星
ProxyInvocationHandler. java 即代理角色
public class Agent implements InvocationHandler { private Singer singer; /** * 设置代理的经济人 * @param singer */ public void setSinger(Singer singer) { this.singer = singer; }
@Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("---------------经纪人把把关--------------");
//一种反射,调用的方法是什么,method就是什么,传什么参数,args就是什么参数
Object returnObj = method.invoke(singer, args); System.out.println("---------------唱完了收收钱------------------------"); return returnObj; } /** * 获取一个代理对象 * @return */ public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), new Class[]{Singer.class},this); } }
Client . java
public class Client { public static void main(String[] args) { MaleSinger luhan = new MaleSinger(); Agent agent = new Agent(); agent.setSinger(luhan); Singer singer = (Singer)agent.getProxy(); singer.sing(); } }
核心:一个动态代理 , 一般代理某一类业务 , 一个动态代理可以代理多个类,代理的是接口!