简体   繁体   中英

What is interface-based proxying?

I was reading this regarding to where to place Transactional(interface vs implementation):

The Spring team's recommendation is that you only annotate concrete classes with the @Transactional annotation, as opposed to annotating interfaces. You certainly can place the @Transactional annotation on an interface (or an interface method), but this will only work as you would expect it to if you are using interface-based proxies. The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy (which would be decidedly bad). So please do take the Spring team's advice and only annotate concrete classes (and the methods of concrete classes) with the @Transactional annotation.

So the question is what is interface-based proxy exactly and how can I see if it is used? Is it some configuration or it is the way how I instantiate/use instances?

If Spring cannot create a JDK proxy (or if you force Spring to create a CGLIB proxy by setting proxyTargetClass to true) then the code will not execute in a transactional context because (as the Spring docs state):

The fact that annotations are not inherited means that if you are using class-based proxies then the transaction settings will not be recognised by the class-based proxying infrastructure and the object will not be wrapped in a transactional proxy

So, I think your concerns are:

How can you be sure that Spring does not create a CGLIB proxy

You must be configuring AOP based transactional support. If you are doing this by using <tx:annotation-driven/> then the default value for proxy-target-class (false) will suffice though could be explicit about this by setting: <tx:annotation-driven proxy-target-class=“false"></tx:annotation-driven> . If you are configuring transactional support in some other way (using Java config, for example) then just ensure that the value of TransactionProxyFactoryBean.proxyTargetClass is false.

How can you be sure that your @Transactional annotations are respected

This is easy, just annotate the concrete class with the @Transactional annotation instead of annotating the interfaces. This avoids any issues with proxying.

In summary, Spring should use interface based proxying as long as TransactionProxyFactoryBean.proxyTargetClass is false however, if you annotate a concrete class rather than an implementation then the issue of proxying won't affect transactional support.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM