tags:

views:

98

answers:

1

I am interested in getting the class being proxied from spring, rather than the proxy.

ie:

public class FooImpl<KittyKat> {

    @Transactional
    public void doStuff() {
        getBar();
        // java.lang.ClassCastException: $Proxy26 cannot be cast to 
        // com.my.foo.Bar   
    }   

}

public abstract class AbstractFoo<T extends AbstractBar> {

    public String barBeanName;

    protected T getBar() {
        // java.lang.ClassCastException: $Proxy26 cannot be cast to 
        // com.my.foo.Bar
    return (T)appContext.getBean(barBeanName);
    }
}  

public class KittyCat extends AbstractBar {
 ...
}

public abstract class AbstractBar {
  ...
}
+1  A: 

Are you trying to get the proxied bean only because of the ClassCastException? If you could cast to Bar, would you happy with that?

When Spring creates a proxy, it checks to see if the bean class implements any interfaces. If it does, then the generated proxy will also implement those interfaces, but it will not extend the target bean's class. It does this using a standard java.lang.reflect.Proxy. This seems to be the case in your example.

If the target bean's class does not implement any interfaces, then Spring will use CGLIB to generate a proxy class which is a subclass of the target bean's class. This is sort of a stop-gap measure for proxying non-interface beans.

You can force Spring to always proxy the target class, but how you do that depends on how you created the Bar proxy to begin with, and you haven't told us that.

The generally preferred solution is to refer to your proxied beans by their interfaces, and everything works nicely. If your Bar class implement interfaces, could your Foo not refer to that interface?

skaffman