首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler

java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler
EN

Stack Overflow用户
提问于 2018-05-22 07:19:13
回答 1查看 617关注 0票数 0

java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler的目的是什么?当我们需要在我们的应用程序上创建和使用这些时?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-05-22 08:27:13

代理是一种设计模式。当我们想要添加或修改一个已经存在的类的某些功能时,我们创建和使用代理对象。使用代理对象而不是原始对象。通常,代理对象具有与原始对象相同的方法,并且在Java代理类中通常扩展原始类。代理具有原始对象的句柄,并可以调用该对象上的方法。

通过这种方式,代理类可以以方便的方式实现许多事情:

  1. 方法启动和停止时的日志记录
  2. 对参数执行额外检查
  3. 模拟原始类的行为
  4. 获得昂贵资源的机会

而不修改类的原始代码。(上面的清单并不广泛,它只列举了一些例子)。

要创建一个实际的动态代理类,只需实现java.lang.reflect.InvocationHandler接口:

代码语言:javascript
复制
public Class MyDynamicProxyClass implements
java.lang.reflect.InvocationHandler
{
  Object obj;
  public MyDynamicProxyClass(Object obj)
  { this.obj = obj; }
  public Object invoke(Object proxy, Method m, Object[] args) throws
Throwable
  {
    try {
      // do something
    } catch (InvocationTargetException e) {
      throw e.getTargetException();
    } catch (Exception e) {
      throw e;
    }
    // return something
  }
}

仅此而已!好吧,好吧,你还必须有你真正的代理接口:

代码语言:javascript
复制
public interface MyProxyInterface
{
  public Object MyMethod();
}

然后,要实际使用动态代理,代码如下所示:

代码语言:javascript
复制
MyProxyInterface foo = (MyProxyInterface)
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                         Class[] { MyProxyInterface.class },
                                         new MyDynamicProxyClass(obj));

知道上面的代码是可怕的丑陋,我想隐藏在某种类型的工厂方法。因此,我将将该方法添加到我的MyDynamicProxyClass中,而不是在客户端代码中包含这些杂乱的代码:

代码语言:javascript
复制
static public Object newInstance(Object obj, Class[] interfaces)
{
  return
java.lang.reflect.Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                                                  interfaces,
                                                  new
MyDynamicProxyClass(obj));
}
That allows me to use the following client code instead:

MyProxyInterface foo = (MyProxyInterface)
  MyDynamicProxyClass.newInstance(obj, new Class[]
{ MyProxyInterface.class });

这代码要干净得多。将来最好有一个工厂类,对客户端完全隐藏整个代码,这样客户端代码看起来更像:

代码语言:javascript
复制
MyProxyInterface foo = Builder.newProxyInterface();

总的来说,实现动态代理相当简单。

参考文献:

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50461939

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档