The methods or classes in Kotlin are final by default. But when I mark a method in a Service class to be @Transactional
, I realised the service class and all its methods are open. Because for the @Transactional
aspect to work, the service class needs to be proxied, then it must be an open class so that the proxy class can extend the original class.
(As the tutorial Open Keyword in Kotlin points out, kotlin is final by default.
According to the Spring documentation AOP, because my service class inherits from an abstract class instead of an interface, so the proxy is a CGLIB proxy.)
Did I misunderstand anything or how does it work?
@Service
class SomeService(...): SomeAbstractClass(...){
@Transactional
fun someMethod(...){...}
}
Indeed, Spring automatically configures Service classes, etc to be open.
Because this is to important to the way Spring and other frameworks work, Kotlin documentation talks about it here: All-open compiler plugin
Kotlin has classes and their members final by default, which makes it inconvenient to use frameworks and libraries such as Spring AOP that require classes to be
open
. Theall-open
compiler plugin adapts Kotlin to the requirements of those frameworks and makes classes annotated with a specific annotation and their members open without the explicitopen
keyword.For instance, when you use Spring, you don't need all the classes to be open, but only classes annotated with specific annotations like
@Configuration
or@Service
. Theall-open
plugin allows you to specify such annotations.Kotlin provides
all-open
plugin support both for Gradle and Maven with the complete IDE integration.For Spring, you can use the
kotlin-spring
compiler plugin.