• 静态代理和动态代理


    一、静态代理

    代理模式(Proxy Pattern)是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。是一种AOP编程思想。

    下面,我们以购买火车票为例,我们可以通过火车站去买票,当一些人不方便时候,可能会通过代售点买票,那么代售点其实可以理解为火车站的代理类,只不过代售点提供了火车站的服务,当然也会收取一定的服务费。

    代码如下:

    1. public class hook {
    2. /**
    3. * 售票服务接口
    4. */
    5. public interface TicketService {
    6. //售票
    7. public void sellTicket();
    8. }
    9. /**
    10. * 售票服务接口实现类,车站
    11. */
    12. public static class Station implements TicketService {
    13. @Override
    14. public void sellTicket() {
    15. System.out.println("\n\t售票.....\n");
    16. }
    17. }
    18. /**
    19. * 车票代售点
    20. *
    21. */
    22. public static class StationProxy implements TicketService {
    23. private final Station station;
    24. public StationProxy(Station station){
    25. this.station = station;
    26. }
    27. @Override
    28. public void sellTicket() {
    29. // 1.做真正业务前,提示信息
    30. System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
    31. // 2.调用真实业务逻辑
    32. station.sellTicket();
    33. // 3.后处理 println
    34. System.out.println("××××欢迎您的光临,再见!××××\n");
    35. }
    36. }
    37. public static void main(String[] args) {
    38. Station changchun = new Station();
    39. StationProxy proxy = new StationProxy(changchun);
    40. proxy.sellTicket();
    41. }
    42. }

    通过以上的代码,还是很容易理解静态代理了,通过代理类去控制实体类的行为,并可以灵活加上之自己的行为~ 

    二、动态代理

    在Java中,动态代理是通过InvocationHandler接口,重写invoke函数实现的。

    还是以火车站售票为例,

    代码如下:

    1. package com.tiancity.dom.lib;
    2. import java.lang.reflect.InvocationHandler;
    3. import java.lang.reflect.Method;
    4. import java.lang.reflect.Proxy;
    5. public class dynamic {
    6. /**
    7. * 售票服务接口
    8. */
    9. public interface TicketService {
    10. //售票
    11. public void sellTicket();
    12. }
    13. /**
    14. * 售票服务接口实现类,车站
    15. */
    16. public static class Station implements TicketService {
    17. @Override
    18. public void sellTicket() {
    19. System.out.println("\n\t售票.....\n");
    20. }
    21. }
    22. /**
    23. * 车票代售点
    24. *
    25. */
    26. public static class StationProxy implements InvocationHandler {
    27. private final TicketService station;
    28. public StationProxy(TicketService station){
    29. this.station = station;
    30. }
    31. //com.sun.proxy.$Proxy0 cannot be cast to
    32. //getInterfaces 获取的是接口,不是类,所以要用TicketService
    33. public Object getProxy(){
    34. return (Object) Proxy.newProxyInstance(this.getClass().getClassLoader(),
    35. station.getClass().getInterfaces(),this);
    36. }
    37. @Override
    38. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    39. Object result = null;
    40. if(method.getName().equals("sellTicket")){
    41. // 1.做真正业务前,提示信息
    42. System.out.println("××××您正在使用车票代售点进行购票,每张票将会收取5元手续费!××××");
    43. // 2.调用真实业务逻辑
    44. result=method.invoke(station, args);
    45. // 3.后处理 println
    46. System.out.println("××××欢迎您的光临,再见!××××\n");
    47. }
    48. return result;
    49. }
    50. }
    51. public static void main(String[] args) {
    52. TicketService dalian = new Station();
    53. StationProxy proxy = new StationProxy(dalian);
    54. TicketService p = (TicketService) proxy.getProxy();
    55. p.sellTicket();
    56. }
    57. }

    三、总结

    代理模式可以在不修改真实类代码的情况下,实现对真实类的访问控制、性能优化等功能。Java 中有两种实现代理模式的方法:静态代理和动态代理。静态代理需要在编译之前手动编写代理类,而动态代理可以在运行时动态生成代理类。

  • 相关阅读:
    关于YOLOv8不显示GFlops的问题解决
    vue中 setState
    Known框架实战演练——进销存系统需求
    【MM小贴士】SAP 批次管理基础配置
    目标检测:二维码检测方案
    变分法 (Calculus of Variations)
    百度用户产品流批一体的实时数仓实践
    Matlab:Matlab编程语言学习之常用运算操作符、常用函数(逻辑函数、运算函数、交互函数等)简介、使用方法之详细攻略
    为什么你的用户转化率不高?-- 新媒体运营转化效果渠道归因分析
    基于大数据的高校英语现状分析
  • 原文地址:https://blog.csdn.net/qq_34123324/article/details/133162570