设计代理类的实际目的是什么? [英] What is the actual purpose of designing a proxy class?

查看:52
本文介绍了设计代理类的实际目的是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在研究代理类,但我不了解设计它的全部想法.

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://www.javassist.org/

https://docs.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html

这篇关于设计代理类的实际目的是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆