我需要一些建议,动态代理比常规代理更有用。
我已经投入了大量精力来学习如何有效地使用动态代理。在这个问题中,抛开像AspectJ这样的框架基本上可以执行我们尝试用动态代理实现的所有内容,或者例如CGLIB可以用来解决动态代理的一些缺点。
其他人吗?
public Object invoke(Object target, Method method, Object[] arguments) {
System.out.println("before method " + method.getName());
return method.invoke(obj, args);
}
}
装饰器模式肯定是有用的,因为它允许所有代理方法的副作用(尽管这种行为是书籍 - 使用方面的例子..)。
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;
}
}
另一方面,合同只能避免实现完整界面的需要。然后,重构代理方法将无声地使动态代理无效。
所以我在这里看到的是一个真实的用例,一个有问题的用例。你有什么看法?
答案 0 :(得分:12)
除了您所描述的内容之外,动态代理还有许多潜在的用途 -
除了上面描述的验证和日志记录之外,这些只是一些选项。 FWIW,JSR 303,一个bean验证规范,在Hibernate Validator中有一个AOP风格的实现,所以你不需要专门为你的数据对象实现它。 Spring框架还内置了验证,并且与AspectJ集成了很好的集成,用于描述这里描述的一些内容。
答案 1 :(得分:11)
事实上,AOP使大多数动态代理受益。那是因为您可以在事先不知道的对象周围创建动态代理。
动态代理的另一个有用方面是当您想对所有方法应用相同的操作时。使用静态代理,您需要大量重复的代码(在每个代理方法上,您需要对方法进行相同的调用,然后委托给代理对象),动态代理将最小化此代码。
另请注意,Adapter和Decorator是单独的模式。它们在实现方式上看起来像代理模式(通过对象组合),但它们有不同的用途:
EnumetationIterator
- 它会将Enumeration
调整为Iterator
界面。答案 2 :(得分:0)
我能想到的另一个用例是在运行时动态实现接口,这是一些框架的工作方式。
以实例Retrofit为例,这是一个用于使用REST服务的Java库。您可以定义一个Java接口,该接口反映REST API中可用的操作,并使用注释来装饰方法以配置请求的细节。很容易看出,在这种情况下,接口中定义的所有方法都必须对某个服务器执行HTTP请求,将方法参数转换为请求参数;然后将响应解析为定义为方法返回类型的java对象。