1

As far as I know, Spring uses JDK to generate dynamic proxy for the classes that implement any inferface while use Cglib to generate dynamic proxy for the classes that do not implement any inferface. For decarative transcation, Spring uses proxy to add transaction aspect. Please take a look at the code below:

interface Demo {
    void methodA();
}
public class DemoImpl implements Demo{
    @Transactional
    public void updateA() {}
    @Transactional
    public void updateB() {}
}

I think updateA can work well with transaction. But how about updateB method? Does the @Transactional work for it? Maybe my understanding is not correct. It's great if the related Spring source code is provided to explain how Spring use JDK/cglib to proxy the class and interface. Thanks

I have the config in the xml:

<tx:annotation-driven transaction-manager="transactionManager" /> 
Jacky
  • 8,619
  • 7
  • 36
  • 40

1 Answers1

1

JDK dynamic proxy

In this case your bean is wrapped with a proxy implementing Demo interface. From that moment you can only use that interface. Trying to inject or fetch bean of DemoImpl type will result in dreadful Abstract DAO pattern and Spring's "Proxy cannot be cast to ..." problem!

This kind of answers your question - you can only access updateA() and this is the only transactional method. Annotation around updateB() is ignored.

However if you call updateB() from updateA() it will be transactional because it will bind to a transaction started by updateA() (with default transaction propagation).

CGLIB proxy

In this case the interface is ignored. will create a subclass of DemoImpl (obviously also implementing Demo interface) and apply transaction behaviour on both update*() methods. Now if you inject bean of type DemoImpl (interface is not needed in this case at all and Impl suffix is ugly) you can safely and transactionally call both methods.

See my article: Spring pitfalls: proxying and Spring AOP riddle for greater details.

Community
  • 1
  • 1
Tomasz Nurkiewicz
  • 334,321
  • 69
  • 703
  • 674
  • Thank you, Tomasz. Which case will Spring choose for me if I have this config: – Jacky May 13 '12 at 09:25
  • 1
    @Jacky: by default Spring uses JDK proxies. It will upgrade to CGLIB proxies if `proxy-target-class` attribute is set, see: [11.5.6 Using @Transactional](http://static.springsource.org/spring/docs/current/spring-framework-reference/html/transaction.html#transaction-declarative-annotations). – Tomasz Nurkiewicz May 13 '12 at 11:22