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" />
JDK dynamic proxy
In this case your bean is wrapped with a proxy implementing
Demointerface. From that moment you can only use that interface. Trying to inject or fetch bean ofDemoImpltype 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 aroundupdateB()is ignored.However if you call
updateB()fromupdateA()it will be transactional because it will bind to a transaction started byupdateA()(with default transaction propagation).CGLIB proxy
In this case the interface is ignored. cglib will create a subclass of
DemoImpl(obviously also implementingDemointerface) and apply transaction behaviour on bothupdate*()methods. Now if you inject bean of typeDemoImpl(interface is not needed in this case at all andImplsuffix is ugly) you can safely and transactionally call both methods.See my article: Spring pitfalls: proxying and Spring AOP riddle for greater details.