如何在java中获取代理对象的基础类型?

bla*_*ank 28 java proxy

我想访问底层类的类名,它是一个实例java.lang.reflect.Proxy.

这可能吗?

Boz*_*zho 24

您可以InvocationHandler通过调用获取创建代理的位置Proxy.getInvocationHandler(proxy)

请注意,在本身java.lang.reflect.Proxy没有基础类的情况下.代理定义如下:

  • 接口(S)
  • 调用处理程序

并且包装的类通常被传递给具体的调用处理程序.

  • 谢谢。调用处理程序会给我带来什么?我有一个代理,但我想要实现代理所构建的接口的对象的类名。我想这是不可能的... (2认同)

Sll*_*ort 21

我在这个网站上找到了一个很好的解决方案(现已存档):

@SuppressWarnings({"unchecked"})
protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception {
  if (AopUtils.isJdkDynamicProxy(proxy)) {
    return (T) ((Advised)proxy).getTargetSource().getTarget();
  } else {
    return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
  }
}
Run Code Online (Sandbox Code Playgroud)

用法

@Override
protected void onSetUp() throws Exception {
  getTargetObject(fooBean, FooBeanImpl.class).setBarRepository(new MyStubBarRepository());
}
Run Code Online (Sandbox Code Playgroud)


Ste*_*n C 15

那么Proxy实例java.lang.reflect.Proxy 本身不是一个实例.相反,它将是一个子类的实例java.lang.reflect.Proxy.

无论如何,获取实际代理类名称的方法是:

Proxy proxy = ...
System.err.println("Proxy class name is " + proxy.getClass().getCanonicalName());
Run Code Online (Sandbox Code Playgroud)

但是,您无法获取Proxy作为代理的类的名称,因为:

  1. 你代理接口而不是类,和
  2. 代理可以是多个接口的代理

但是,从查看ProxyGenerator类的源代码,似乎接口被记录在生成的代理类中作为类的接口.所以你应该能够通过代理类Class对象在运行时获取它们; 例如

Class<?>[] classes = proxy.getClass().getInterfaces();
Run Code Online (Sandbox Code Playgroud)

(注意:我没试过这个...)

  • `proxy.getClass().getInterfaces()`完美无缺! (3认同)

win*_*ne2 8

简单而坚固:

AopUtils.getTargetClass(object).getName(); 
Run Code Online (Sandbox Code Playgroud)

也适用于 CGLIB 代理和非代理对象。


lbo*_*oix 5

这是我们与团队一起使用的解决方案(我们需要代理背后的类名称):

if (getTargetName(yourBean) ... ) {

}
Run Code Online (Sandbox Code Playgroud)

有了这个小帮手:

private String getTargetName(final Object target) {

    if (target == null) {
        return "";
    }

    if (targetClassIsProxied(target)) {

        Advised advised = (Advised) target;

        try {

            return advised.getTargetSource().getTarget().getClass().getCanonicalName();
        } catch (Exception e) {

            return "";
        }
    }

    return target.getClass().getCanonicalName();
}

private boolean targetClassIsProxied(final Object target) {

    return target.getClass().getCanonicalName().contains("$Proxy");
}
Run Code Online (Sandbox Code Playgroud)

希望能帮助到你!