将Spring的Proxy对象转换为实际的运行时类

sse*_*ano 12 java spring

我正在使用Spring,有一点我想将对象转换为它的实际运行时实现.

例:

Class MyClass extends NotMyClass {
    InterfaceA a;
    InterfaceA getA() { return a; }

    myMethod(SomeObject o) { ((ImplementationOfA) getA()).methodA(o.getProperty()); }
}
Run Code Online (Sandbox Code Playgroud)

那喊一个ClassCastException,因为a是一个$ProxyN对象.虽然在beans.xml中我注入了一个类的bean ImplementationOfA.

编辑1 我扩展了一个类,我需要调用一个方法ImplementationOfA.所以我想我需要施展.该方法接收参数.

编辑2

我最好扯掉目标类:

private T getTargetObject(Object proxy, Class targetClass) throws Exception {
    while( (AopUtils.isJdkDynamicProxy(proxy))) {
        return (T) getTargetObject(((Advised)proxy).getTargetSource().getTarget(), targetClass);
    }
    return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class
}
Run Code Online (Sandbox Code Playgroud)

我知道它不是很优雅但有效.

所有学分归http://www.techper.net/2009/06/05/how-to-acess-target-object-behind-a-spring-proxy/ 谢谢!

aba*_*ogh 8

你为什么要演员?关于Spring代理使用这是一篇很棒的文章,我建议你阅读它,评论也是如此.

以及Spring AOP文档中的代理(7.1.3)部分.


siu*_*lki 7

对我来说,编辑2的版本没有用.下面有一个工作:

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

用法:

    UserServicesImpl serviceImpl = getTargetObject(serviceProxy);
    serviceImpl.setUserDao(userDAO);
Run Code Online (Sandbox Code Playgroud)


Rob*_*sin 7

现在你可以使用

AopTestUtils.getTargetObject(proxy)
Run Code Online (Sandbox Code Playgroud).

实现与@siulkilulki sugestion 相同,但它在 Spring helper 上


Val*_*udi -1

基本上当你在Spring中使用AOP时,Spring会为你构建一个Proxy。您有两个选择:

  1. 当您在实现接口的 bean 上应用切面时,在本例中 Spring 使用 JdkDynamicProxy
  2. 当你的 spring bean 没有实现任何接口并且你的类路径中有 cglib 2.2 时,请考虑从 spring 3.2.x 开始,默认情况下你在 spring 容器中拥有 cglib,spring 使用一个名为 CGLibProxy 的特殊代理。

这里的关键点是,当一个方面应用于您的 bean 时,Spring 将实例化一个代理,如果您尝试执行强制转换,您将得到一个异常。

我希望这可以帮助你