筹划模式 - 署理模式

[复制链接]
发表于 2025-9-28 14:46:59 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
署理模式

署理模式是一种结构型筹划模式,它答应你提供一个署理对象来控制对另一个对象的访问。署理模式可以在不改变原始对象的环境下,增强或控制对原始对象的访问。署理模式通常用于耽误加载、访问控制、日记记载、性能监控监控等场景。
1.静态署理

静态署理是指在编译时就已经确定署理类和被署理类的关系。静态署理通常必要手动编写署理类,而且署理类和被署理类实现类似的接口或继续类似的父类
  1. public interface OrderService {
  2.     void save();
  3. }
  4. public class ProxyOrderService implements OrderService {
  5.     // 被代理的对象
  6.     private OrderService orderService;
  7.     public ProxyOrderService(OrderService orderService) {
  8.         this.orderService = orderService;
  9.     }
  10.     // 执行
  11.     public static void main(String[] args) {
  12.         // 创建被代理对象
  13.         OrderService orderService = new OrderServiceImpl();
  14.         // 创建代理对象
  15.         ProxyOrderService proxy = new ProxyOrderService(orderService);
  16.         proxy.save();
  17.     }
  18.     @Override
  19.     public void save() {
  20.         System.out.println("代理前置处理 ...");
  21.         // 执行被代理的对象的方法
  22.         orderService.save();
  23.         System.out.println("代理后置处理 ...");
  24.     }
  25. }
复制代码
2 动态署理

动态署理是指在运行时动态天生署理类,而不是在编译时手动编写署理类。
2.1 JDK动态署理

JDK动态署理基于Java反射机制实现,它必要被署理对象实现一个接口。
  1. /**
  2. * 代理对象 实现 InvocationHandler
  3. * InvocationHandler 该类做方法拦截所用, 通过此类可以对目标方法进行增强
  4. */
  5. public class JDKProxyDynamic implements InvocationHandler, Serializable {
  6.     private static final long serialVersionUID = 4431939583048226878L;
  7.     private Object target;
  8.     private Class<?> clazz;
  9.     public JDKProxyDynamic(Class<?> clazz) {
  10.         this.clazz = clazz;
  11.     }
  12.     /**
  13.      * 通过该方法的调用对目标对象进行增强
  14.      */
  15.     @Override
  16.     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  17.         System.out.println("调度真实对象之前,方法名: " + method.getName() + ",参数:" + args);
  18.         // Spring框架中使用动态代理,可以从applicationContext里面获取对应的target对象
  19.         if (Objects.isNull(target)) {
  20.             target = clazz.newInstance();
  21.         }
  22.         System.out.println("代理前置处理 ...");
  23.         Object returnResult = method.invoke(target, args);
  24.         System.out.println("代理后置处理 ...");
  25.         return returnResult;
  26.     }
  27.     public static void main(String[] args) {
  28.         // 创建动态代理对象,JDK动态代理只能代理实现接口的类
  29.         OrderService proxyInstance = (OrderService) Proxy.newProxyInstance(
  30.                 OrderServiceImpl.class.getClassLoader(),
  31.                 OrderServiceImpl.class.getInterfaces(),
  32.                 new JDKProxyDynamic(OrderServiceImpl.class)
  33.         );
  34.         // 通过代理对象调用方法
  35.         proxyInstance.save();
  36.     }
  37. }
复制代码
2.2 CGLIB动态署理

CGLIB动态署理基于ASM字节码天生框架实现,它不必要被署理对象实现接口。CGLIB动态署理是针对类举行署理的,它通过继续目标类创建子类,并重写目标类的方法。
  1. public class CglibProxy implements MethodInterceptor {
  2.     private static CglibProxy INSTANCE = new CglibProxy();
  3.     private Object target;
  4.     private Class<?> clazz;
  5.     private CglibProxy() {
  6.     }
  7.     public CglibProxy(Class<?> clazz) {
  8.         this.clazz = clazz;
  9.     }
  10.     public static CglibProxy getInstance() {
  11.         return INSTANCE;
  12.     }
  13.     public Object getCglibProxyObject(Object target) {
  14.         // 可以在Spring中获取指定对象,为其创建代理对象,再指定对应的target
  15.         this.clazz = target.getClass();
  16.         this.target = target;
  17.         Enhancer enhancer = new Enhancer();
  18.         enhancer.setSuperclass(target.getClass());
  19.         enhancer.setCallback(this);
  20.         return enhancer.create();
  21.     }
  22.     /**
  23.      * @param object 被代理的对象
  24.      * @param method 被代理对象需要执行的方法
  25.      * @param args   被代理对象需要执行的方法 参数
  26.      * @param proxy  触发父类的方法对象
  27.      * @return 被代理对象需要执行的方法 返回值
  28.      * @throws Throwable 抛出的异常信息
  29.      */
  30.     @Override
  31.     public Object intercept(Object object, Method method, Object[] args, MethodProxy proxy) throws Throwable {
  32.         System.out.println("Before method execution: " + method.getName());
  33.         Object result = proxy.invokeSuper(object, args);
  34.         System.out.println("After method execution: " + method.getName());
  35.         return result;
  36.     }
  37.     public static void main(String[] args) {
  38.         Enhancer enhancer = new Enhancer();
  39.         enhancer.setSuperclass(OrderServiceImpl.class);
  40.         enhancer.setCallback(new CglibProxy());
  41.         OrderService orderService = (OrderService) enhancer.create();
  42.         orderService.save();
  43.     }
  44. }
复制代码
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表