Spring-代理模式
学习视频:
B站 狂神说Java之Spring5教程:https://www.bilibili.com/video/BV1WE411d7Dv
代理模式
-
定义
为其他对象提供一种代理以控制对这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
-
组成:
- 抽象角色:通过接口或抽象类声明真实角色实现的业务方法。
- 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。
- 真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
-
代理模式类别
- 静态代理
- 动态代理
静态代理
静态代理:由程序员创建或特定工具自动生成源代码,也就是在编译时就已经将接口、被代理类、代理类等确定下来。在程序运行之前,代理类的.class文件就已经生成。
租房实例:
-
Rent.java
//抽象角色:租房 public interface Rent { public void rent(); }
-
HouseMaster.java
//真是角色,房主 public class HouseMaster implements Rent{ @Override public void rent() { System.out.println("房东:我要出租房屋"); } }
-
ProxyRent.java
//代理角色:中介 public class ProxyRent { private HouseMaster houseMaster; public ProxyRent(){ } public ProxyRent(HouseMaster houseMaster){ this.houseMaster = houseMaster; } //租房 public void rent(){ houseMaster.rent(); watch(); contract(); getFee(); } //看房 public void watch(){ System.out.println("看房"); } //签合同 public void contract(){ System.out.println("签合同"); } //收取中介费 public void getFee(){ System.out.println("交易成功,收取中介费"); } }
-
Client.java
//客户类 public class Client { public static void main(String[] args) { //房东出租房 HouseMaster houseMaster = new HouseMaster(); //中介代理房东去出租房子 ProxyRent proxy = new ProxyRent(houseMaster); //客户找中介租房 proxy.rent(); } }
-
结果
静态代理的好处:
- 可以使得我们的真实角色更加纯粹 . 不再去关注一些公共的事情 .
- 公共的业务由代理来完成 . 实现了业务的分工 ,
- 公共业务发生扩展时变得更加集中和方便 .
缺点 :
- 类多了 , 多了代理类 , 工作量变大了 ,开发效率降低 .
我们想要静态代理的好处,又不想要静态代理的缺点,所以 , 就有了动态代理
动态代理
代理类在程序运行时创建的代理方式被成为动态代理。
-
动态代理的角色和静态代理的相同
-
动态代理的代理类是动态生成的 , 静态代理的代理类是我们提前写好的
-
动态代理分为两类 : 一类是基于接口动态代理 , 一类是基于类的动态代理
-
-
基于接口的动态代理—-JDK动态代理【主要使用】
-
基于类的动态代理–CGLIB
-
JDK动态代理(基于反射实现):通过InvocationHandler接口和Proxy类生成JDK动态代理类和动态代理对象。
实例:
-
Rent.java
public interface Rent { public void rent(); }
-
HouseMaster.java
public class HouseMaster implements Rent { @Override public void rent() { System.out.println("房东:我要出租房屋"); } }
-
ProxyInvocationHandler.java
public class ProxyInvocationHandler implements InvocationHandler { //被代理的接口 private Rent rent; public void setRent(Rent rent) { this.rent = rent; } //生成得到的代理类 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = method.invoke(rent, args); watch(); fee(); return result; } public void watch(){ System.out.println("中介带租客看房"); } public void fee(){ System.out.println("中介收取中介费"); } }
-
Client.java
public class Client { public static void main(String[] args) { //真实角色 HouseMaster houseMaster = new HouseMaster(); //代理角色:需要创建 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //将真实角色放置进去 pih.setRent(houseMaster); //动态生产代理类 Rent proxy = (Rent) pih.getProxy(); proxy.rent(); } }
-
测试结果
业务实例:
-
UserService.java
public interface UserService { public void add(); public void delete(); public void update(); public void query(); }
-
UserServiceImpl.java
public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("使用了add方法"); } @Override public void delete() { System.out.println("使用了delete方法"); } @Override public void update() { System.out.println("使用了update方法"); } @Override public void query() { System.out.println("使用了query方法"); } }
-
ProxyInvocationHandler.java
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 { log(method.getName()); Object result = method.invoke(target, args); return result; } public void log(String str){ System.out.println("调用了"+str+"方法"); } }
-
Client.java
public class Client { public static void main(String[] args) { //真实角色 UserServiceImpl userService = new UserServiceImpl(); //代理对象的调用处理程序 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //需要代理真实角色 pih.setTarget(userService); //生产代理类 UserService proxy = (UserService) pih.getProxy(); proxy.add(); // proxy.delete(); // proxy.update(); // proxy.query(); } }
-
测试结果
动态代理的好处
- 可以使得我们的真实角色更加纯粹,不再去关注一些公共的事情
- 公共的业务由代理来完成,实现了业务的分工
- 公共业务发生扩展时变得更加集中和方便
- 一个动态代理 , 一般代理某一类业务
- 一个动态代理可以代理多个类,代理的是接口
知识点补充:
Method类方法功能:
invoke():实现对方法的动态调用
getName():返回方法对象的名称
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/147370.html