Search code examples
javaspringproxyspring-aopcglib

Does proxy-target-class="true"disable interface-based proxy?


I would like to set all proxy-related annotations like @Transactional, @Async, @Cacheable on my interfaces method. The main reason is that I have multiple implementations, so I don't want to repeat the same annotations each time I add a new implementation.

Reading the documentation I fell on this:

The Spring team recommends that you annotate only concrete classes (and methods of 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 works only as you would expect it to if you use interface-based proxies. The fact that Java annotations are not inherited from interfaces means that, if you use class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), the transaction settings are not recognized by the proxying and weaving infrastructure, and the object is not wrapped in a transactional proxy.

My questions are: Does proxy-target-class="true" completely disable interface-based proxy? Even if the bean in question implements an interface?

If yes, is it possible to have both proxy types?


Solution

  • Of course you can have both proxy types in one application. Simply do not use proxy-target-class="true". Then if your class implements any interfaces, Spring will generate Java dynamic proxies for them. If your class does not implement any interfaces, it will automatically use a CGLIB class-based proxy. But of course, an interface-based proxy will only contain methods from all the implemented interfaces, not any super-class methods defined on base classes which are not part of any interfaces. So while you get the best of both worlds like this, of course you cannot eat the cake and keep it.

    BTW, the usage mode I just described is even the default in Spring Core. Caveat: It is not the default in Spring Boot, and it is a bit tricky (but possible) to activate it in Boot.