java - Java 动态代理与常规代理的有用性

标签 java design-patterns proxy dynamic-proxy use-case

我需要一些建议,以了解动态代理在哪些情况下比常规代理更有用。

我付出了很多努力来学习如何有效地使用动态代理。在这个问题中,抛开像 AspectJ 这样的框架基本上可以执行我们试图用动态代理实现的一切,或者说,例如,CGLIB 可以用来解决动态代理的一些缺点。

用例

  • 装饰器 - 例如,对方法调用执行日志记录,或缓存复杂操作的返回值
  • 维护契约(Contract) - 也就是说,确保参数在可接受的范围内并且返回类型符合可接受的值。
  • 适配器 - 在某处看到一些聪明的文章,描述了它的用处。不过我很少遇到这种设计模式。

其他人呢?

动态代理优势

  • 装饰器:记录所有方法调用,例如,

public Object invoke(Object target, Method method, Object[] arguments) {
         System.out.println("before method " + method.getName());
         return method.invoke(obj, args);
     }
}

装饰器模式绝对有用,因为它允许对所有代理方法产生副作用(尽管这种行为是使用方面的书本示例......)。

  • 契约(Contract):与常规代理相比,我们不需要实现完整的接口(interface)。例如,

public Object invoke(Object target, Method method, Object[] arguments) {
     if ("getValues".equals(method.getName()) {
         // check or transform parameters and/or return types, e.g., 
         return RangeUtils.validateResponse( method.invoke(obj, args) );
     }

     if ("getVersion".equals(method.getName()) {
         // another example with no delegation
         return 3;
     }
} 

另一方面,契约只提供避免实现完整接口(interface)的需要的好处。话又说回来,重构代理方法会默默地使动态代理无效。

结论

所以我在这里看到的是一个真实的用例,以及一个有问题的用例。你怎么看?

最佳答案

除了您所描述的之外,动态代理还有许多潜在用途 -

  1. 事件发布 - 在方法 x() 上,透明地调用 y() 或发送消息 z。
  2. 事务管理(用于数据库连接或其他事务操作)
  3. 线程管理 - 透明地线程化昂贵的操作。
  4. 性能跟踪 - 例如,由 CountdownLatch 检查的计时操作。
  5. 连接管理 - 考虑 Salesforce 的企业 API 等 API,这些 API 要求其服务的客户端在执行任何操作之前启动 session 。
  6. 更改方法参数 - 如果您想为空值传递默认值,如果您喜欢这种情况。

除了您上面描述的验证和日志记录之外,这些只是几个选项。 FWIW,JSR 303,一个 bean 验证规范,在 Hibernate Validator 中有一个 AOP 风格的实现,所以你不需要专门为你的数据对象实现它。 Spring 框架还内置了验证功能,并且与 AspectJ 非常好地集成了这里描述的一些内容。

关于java - Java 动态代理与常规代理的有用性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3696068/

相关文章:

java - 玩!用作第二个 Play 项目的库依赖项的框架项目

java - 从保存在 ArrayList 中的对象输出字符串值

java - 为 Java 客户端实现故障转移模式的最佳方法

java - 如何为 final类创建动态代理?

c - 使用C套接字编程获取网页

proxy - 从 XSD 生成类型/类的参数化构造函数

java - 有人可以向我详细解释 'this' 的用法吗?

java - 如何编写为 firebase 调用数据库子级的代码

java - 为什么偏爱静态成员类而不是非静态成员类(Joshua Bloch Item #22)?

python - Python 中的通用命令模式和命令调度模式