代理模式:静态代理与动态代理(Java实例)

悠悠 2021-09-09 05:36 539阅读 0赞

代理模式的角色分析

抽象角色:一般会使用接口或者抽象类来解决

真实角色:被代理的角色

代理角色:代理真实角色,一般都在代理真实角色后,会做一些附属操作

客户:访问代理对象的实体


实例:房东出租房屋,找中介代理,客户之间找中介租房

使用静态代理:

接口:

  1. public interface Rent {
  2. void rent();
  3. }

房东Host

  1. // 房东
  2. public class Host implements Rent {
  3. @Override
  4. public void rent() {
  5. System.out.println("房东出租房子");
  6. }
  7. }

代理中介Proxy

  1. //中介
  2. public class Proxy implements Rent {
  3. private Host host;
  4. public Host getHost() {
  5. return host;
  6. }
  7. public void setHost(Host host) {
  8. this.host = host;
  9. }
  10. public Proxy(Host host) {
  11. this.host = host;
  12. }
  13. @Override
  14. public void rent() {
  15. seehouse();
  16. host.rent();
  17. hetong();
  18. }
  19. public void hetong() {
  20. System.out.println("签合同");
  21. }
  22. public void seehouse() {
  23. System.out.println("带客户去看房");
  24. }
  25. }

客户Client

  1. public class Client {
  2. public static void main(String[] args) {
  3. // 直接房东出租房子
  4. Host host = new Host();
  5. // host.rent();
  6. // 通过中介租房族
  7. Proxy proxy = new Proxy(host);
  8. proxy.rent();
  9. }
  10. }

测试:

20210729122719811.png


使用动态代理方式:

  • 动态代理和静态代理的角色一样
  • 动态代理的代理类是动态生成的,不是我们直接写好的
  • 动态代理分两类

    • 基于接口的动态代理(基于JDK)
    • 基于类的动态代理(基于cglib)

重点两个类的使用:Proxy(代理),InvocationHandler(调用处理程序)

依旧用上面的实例演示

接口:

  1. public interface Rent {
  2. void rent();
  3. }

Host

  1. //房东
  2. public class Host implements Rent{
  3. @Override
  4. public void rent() {
  5. System.out.println("出租房子");
  6. }
  7. }

动态代理类

  1. public class ProxyInvocationHandler implements InvocationHandler {
  2. // 被代理的接口
  3. private Rent rent;
  4. public void setRent(Rent rent) {
  5. this.rent = rent;
  6. }
  7. // 生成得到的代理类
  8. public Object getProxy(){
  9. return Proxy.newProxyInstance(this.getClass().getClassLoader(), rent.getClass().getInterfaces(), this);
  10. }
  11. // 处理代理实例,并返回结果
  12. @Override
  13. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  14. Object result = method.invoke(rent, args);
  15. return result;
  16. }
  17. }

测试:

  1. public class Client {
  2. public static void main(String[] args) {
  3. // 真实角色
  4. Host host = new Host();
  5. // 调用程序处理角色来处理我们要调用的接口对象
  6. ProxyInvocationHandler pih = new ProxyInvocationHandler();
  7. pih.setRent(host);
  8. Rent proxy = (Rent) pih.getProxy();
  9. proxy.rent();
  10. }
  11. }

结果:

20210729123950254.png


代理模式的好处:

  • 可以使真实角色的操作更加纯粹,不用去关注一一些公共的业务
  • 公共也就交给了代理角色,实现了业务的分工
  • 公共业务方式扩展的时候,方便集中管理

上面的动态代理类可以写成下面的封装通用的形式:

  1. public class ProxyInvocationHandler implements InvocationHandler {
  2. // 被代理的接口
  3. private Object target;
  4. public void setRent(Object target) {
  5. this.target = target;
  6. }
  7. // 生成得到的代理类
  8. public Object getProxy(){
  9. return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(), this);
  10. }
  11. // 处理代理实例,并返回结果
  12. @Override
  13. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  14. Object result = method.invoke(target, args);
  15. return result;
  16. }
  17. }

上面实例整理参考自B站狂神编程教程视频

有不对的地方欢迎指正哦!!!!

O(∩_∩)O哈哈~,觉得不错点赞支持一下哦!!!

发表评论

表情:
评论列表 (有 0 条评论,539人围观)

还没有评论,来说两句吧...

相关阅读