设计代理类的实际目的是什么? [英] What is the actual purpose of designing a proxy class?
问题描述
我一直在研究代理类,但我不了解设计它的全部想法.
I've been studying the proxy classes and I don't get the whole idea of designing it.
据我目前所知,它是一个包装对象,可以控制对原始对象的访问.但是如果我们想控制它,为什么我们不能用那些访问机制来设计原始类.
From what I learned so far it is a wrapper object that can control access to the original object. But if we want to control it why can't we design the original class with those access mechanisms.
我读到这些代理对象对于跟踪方法调用、将方法调用路由到远程服务器很有用.
I read that these proxy objects are useful for tracing method calls, routing method calls to remote servers.
但是我在 java 中搜索了一个可以向我解释这一点的问题,但我没有找到.
But I searched for a question that would explain this to me in java but I didn't find any.
我将说明我所指的书中的方法跟踪程序的代码.
I'll illustrate the code for a method tracing program which was in the book that I was referring.
public class ProxyTest {
public static void main(String[] args) throws ClassNotFoundException {
var elements = new Object[1000];
// fill elements with proxies for the integers 1 . . . 1000
for (int i = 0; i < elements.length; i++) {
Integer value = i + 1;
var handler = new TraceHandler(value);
Object proxy = Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Comparable.class}, handler);
elements[i] = proxy;
}
// construct a random integer
Integer key = new Random().nextInt(elements.length) + 1;
// search for the key
int result = Arrays.binarySearch(elements, key);
// print match if found
if (result >= 0)
System.out.println(elements[result]);
}
}
/**
* An invocation handler that prints out the method name and parameters, then
* invokes the original method
**/
class TraceHandler implements InvocationHandler{
private Object target;
/**
* Constructs a TraceHandler
* @param t the implicit parameter of the method call
**/
public TraceHandler(Object t){
target = t;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
// print implicit argument
System.out.print(target);
// print method name
System.out.print("." + m.getName() + "(");
// print explicit arguments
if (args != null){
for (int i = 0; i < args.length; i++){
System.out.print(args[i]);
if (i < args.length - 1)
System.out.print(", ");
}
}
System.out.println(")");
// invoke actual method
return m.invoke(target, args);
}
}
有人可以向我指出这种代理设计模式是怎么回事吗,它在这个特定程序中的作用及其优势?
Can someone please point out to me what is going on with this proxy design pattern, what does it do in this particular program and its advantages?
推荐答案
非常广泛的问题:
对此有几个不同的选择:
there are several different options around this:
- 代理模式 - 一种通过另一个思想第三个对象操纵一个对象的方式
- 延迟加载也可能成为讨论的一部分
- 最后是最流行的 - 编译后的动态代理和代码增强.许多著名的框架都以这种方式工作(例如 spring、hibernate、selenium).这允许实现更具可读性的代码并提高其质量(更少的错误).动态代理带来动态延迟初始化的可能性、代码增强、更多声明性代码
例如工作中的spring事务注释
E.g. spring transactional annotation in work
class UsersDao {
@Transactional
public void method() {
// DO SOME STUFF
}
}
Spring 正在创建扩展"UsersDao 的动态代理,但确实将所有方法调用重定向到实现 InvocationHandler 接口的特定对象
Spring is creating dynamic proxy that "extends" UsersDao but realy does redirect all method invocations to a specific object that implement InvocationHandler interface
InvocationHandler 示例
example of InvocationHandler
public interface InvocationHandler {
/**
* Processes a method invocation on a proxy instance and returns
* the result. This method will be invoked on an invocation handler
* when a method is invoked on a proxy instance that it is
* associated with.
*/
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
在invoke"spring 内部正在做这样的事情:
Inside "invoke" spring is doing something like that:
Transaction tx = TransactionManager.createTransaction()
try {
// execute method
method.invoke();
tx.commit()
}
catch (Exception e) {
// execute callback
tx.rollback()
}
finally () {
// do clean up
// tx.flush()
}
这是通过动态代理的魔力实现的
That is achieved by a magic of dynamic proxies
动态代理工具:
https://github.com/cglib/cglib/wiki
https://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html
这篇关于设计代理类的实际目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!