17

I'm using Spring, at one point I would like to cast the object to its actual runtime implementation.

Example:

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

    myMethod(SomeObject o) { ((ImplementationOfA) getA()).methodA(o.getProperty()); }
}

That yells a ClassCastException since a is a $ProxyN object. Although in the beans.xml I injected a bean which is of the class ImplementationOfA .

EDIT 1 I extended a class and I need to call for a method in ImplementationOfA. So I think I need to cast. The method receives a parameter.

EDIT 2

I better rip off the target class:

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
}

I know it is not very elegant but works.

All credits to http://www.techper.net/2009/06/05/how-to-acess-target-object-behind-a-spring-proxy/ Thank you!

ssedano
  • 8,322
  • 9
  • 60
  • 98

3 Answers3

14

Now you can use

AopTestUtils.getTargetObject(proxy)
.

The implementation is the same of @siulkilulki sugestion, but it's on Spring helper

Roberto Rosin
  • 141
  • 1
  • 4
13

For me version from EDIT 2 didn't worked. Below one worked:

@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
}

Usage:

    UserServicesImpl serviceImpl = getTargetObject(serviceProxy);
    serviceImpl.setUserDao(userDAO);
siulkilulki
  • 1,054
  • 1
  • 10
  • 18
-1

Basically when you use AOP in Spring, Spring build a Proxy for you. You have two option:

  1. when you apply an aspect on a bean that implements an interface, in this case Spring use JdkDynamicProxy
  2. when your spring bean don't implements any interface and if you have cglib 2.2 in you classpath, consider that from spring 3.2.x you have cglib in the spring container by default, spring use a special proxy called CGLibProxy.

The key point here is that when an aspect is applied on your bean Spring will instance a proxy and if you try to perform a cast you will get an exception.

I hope tha this can help you

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Valerio Vaudi
  • 4,199
  • 2
  • 24
  • 23