Java 铸造弹簧';将代理对象添加到实际运行时类

Java 铸造弹簧';将代理对象添加到实际运行时类,java,spring,Java,Spring,我正在使用Spring,有一次我想将对象转换为它的实际运行时实现 例如: Class MyClass extends NotMyClass { InterfaceA a; InterfaceA getA() { return a; } myMethod(SomeObject o) { ((ImplementationOfA) getA()).methodA(o.getProperty()); } } 因为a是一个$ProxyN对象,所以它会喊出一个ClassCastE

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

例如:

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

    myMethod(SomeObject o) { ((ImplementationOfA) getA()).methodA(o.getProperty()); }
}
因为
a
是一个
$ProxyN
对象,所以它会喊出一个
ClassCastException
。尽管我在beans.xml中注入了一个bean,它属于
实现类a

编辑1 我扩展了一个类,需要在的实现中调用一个方法。所以我想我需要投。该方法接收一个参数

编辑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
}
我知道它不是很优雅,但很管用

全部归功于
谢谢大家!

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

  • 当您在实现接口的bean上应用方面时,在 本例中Spring使用JdkDynamicProxy
  • 当您的Springbean没有实现任何接口时 在你的类路径中的CGLIB 2.2,考虑从Spring 3.2。x 默认情况下,spring在spring容器中使用特殊的 名为CGLibProxy的代理
  • 这里的关键点是,当一个方面应用于您的bean时,Spring将实例一个代理,如果您尝试执行强制转换,您将得到一个异常


    我希望这能帮助你

    为我编辑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
    }
    
    现在你可以用了

    AopTestUtils.getTargetObject(proxy)

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

    这是一种糟糕的做法,实际的实现类不应该相关。但是,这是可能的,具体取决于代理的创建方式。如果需要在
    实现上调用方法a
    ,则将该方法添加到
    接口a
    接口,或者定义第二个接口并将该方法添加到该接口。我知道这并不理想,但我正在扩展的类实现了一个接口,由于应用程序的要求,我既不能修改InterfaceA也不能修改NotMyClass。@因此,我要去掉这些要求。我通过访问目标类解决了这个问题。
    AopTestUtils.getTargetObject(proxy)