- 代理模式是Spring中AOP的底层原理
1. 静态代理
角色分析:
- 抽象角色:一般会使用接口或者抽象类来解决
- 真实角色:被代理的角色
- 代理角色:代理真是角色,代理真实角色后,会做一些附属操作
- 客户:访问代理对象的人
代码步骤:
-
接口
//租房 public interface Rent { void rent(); }
-
真实角色
//房东 public class Host implements Rent{ @Override public void rent() { System.out.println("房东要出租房子"); } }
-
代理角色
//中介 public class Proxy implements Rent{ private Host host; public Proxy(){ } public Proxy(Host host){ this.host = host; } @Override public void rent() { seeHouse(); host.rent(); agreement(); fare(); } //看房 public void seeHouse(){ System.out.println("中介带你看房"); } //签合同 public void agreement(){ System.out.println("签房屋租赁合同"); } //收中介费 public void fare(){ System.out.println("收中介费"); } }
-
客户端访问代理角色
public class Client { public static void main(String[] args) { //房东要出租房子 Host host = new Host(); //代理,中介帮房东出租房子,代理角色一般会有一些附属操作 Proxy proxy = new Proxy(host); //直接找中介租房 proxy.rent(); } }
代理模式的好处:
- 可以使真实角色的操作更加纯粹,不用去关注公共的业务
- 公共业务交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
缺点:
- 一个真实的角色就会产生一个代理角色,代码量会翻倍,开发效率会变低
2. 动态代理
- 动态代理和静态代理角色一样
- 动态代理的代理类是动态生成的,不是直接写好的
- 动态代理分为两大类:基于接口的动态实现,基于类的动态实现
- 基于接口 — jdk动态代理【主要使用】
- 基于类 — cglib
- java字节码实现:javassist
需要的两个类:Proxy 和 InvocationHandler
代码步骤:
-
接口
//租房 public interface Rent { void rent(); }
-
真实角色
//房东 public class Host implements Rent { @Override public void rent() { System.out.println("房东要出租房子"); } }
-
动态代理类(万能动态代理类)
//用这个类自动生成代理类 public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Object target; public void setTarget(Object target) { this.target = target; } //生成得到代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } //处理代理实例,并返回结果 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { seeHouse(); //动态代理的本质就是使用反射机制 Object result = method.invoke(target, args); agreement(); fare(); return result; } //看房 public void seeHouse(){ System.out.println("中介带你看房"); } //签合同 public void agreement(){ System.out.println("签房屋租赁合同"); } //收中介费 public void fare(){ System.out.println("收中介费"); } }
-
客户端访问
public class Client { public static void main(String[] args) { //真实角色 Host host = new Host(); //代理角色 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //通过调用程序处理角色来处理我们要调用的接口对象 pih.setTarget(host); //动态生成代理类 Rent proxy = (Rent) pih.getProxy(); proxy.rent(); } }
动态代理的好处:
- 可以使真实角色的操作更加纯粹,不用去关注公共的业务
- 公共业务交给代理角色,实现了业务的分工
- 公共业务发生扩展的时候,方便集中管理
- 一个动态代理类可以代理多个类,只要实现了同一个接口即可