Announcement Announcement Module
No announcement yet.
Annotation/Interface Conflict? Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Annotation/Interface Conflict?

    I've encountered strange behavior which I can't explain. I have a DAO class, defined as a normal Spring bean. I get an instance of it by caling ApplicationContext.getBean(). This worked fine until today, when I had the class implement a simple interface. Now I suddenly began getting class cast exceptions becaase the getBean() method returned an object of class $Proxy10 instead of the DAO class I had been expecting.

    After some trial and error, I discovered the getBean() call returned the $Proxy10 object only when the class implemented the interface and had a method annotated as @Transactional. When I didn't implement the interface, or when I removed the @Transactional annotation, the getBean() method worked perfectly. But when I had both the interface implementation and the annotation, I got the dreaded $Proxy10 object.

    I'm using Spring 2.5.6.

    Anyone have any ideas what causes this?

  • #2
    You might want to have a read of the reference manual, there's some information on dynamic proxies which should help explain what you're seeing.


    • #3
      Well, yes, I've read that more than once, but didn't see anything that describes this behavior. What specifically are you referring to that I'm missing?


      • #4
        So if you try and cast it to the interface it's going to work fine, if you cast it to the class you get a ClassCastException.
        If the target object to be proxied implements at least one interface then a JDK dynamic proxy will be used. All of the interfaces implemented by the target type will be proxied. If the target object does not implement any interfaces then a CGLIB proxy will be created.
        So @Transactional means it's going to get proxied and then follow those rules. When you call getBean you aren't dealing with the raw type you are dealing with a proxy instead. If you remove the interface you're going to force it to proxy the class instead which uses a different kind of proxy hence the different behaviour.