all-open
- Kotlin course
- Expert
- Lesson 16/47
- 5 min
Learn the all-open compiler plugin.
The all-open plugin
The all-open plugin makes Kotlin classes with certain annotations open at compile time. This is needed for framework proxies.
Spring's @Configuration, @Service and similar annotations require a CGLIB proxy, which needs the class to be open. In Kotlin classes are final by default. The all-open plugin is added with the open-for-annotation dependency and you declare in Gradle which annotations should be opened. You no longer mark classes open by hand. This is a standard setup in Spring and Micronaut projects.
An all-open example
In this lesson we show by hand what the all-open plugin does. Normally the plugin adds open automatically; here we model it.
Example: open class Entity(val id: Int) { open fun describe(): String = "Entity #$id" }. Then class UserEntity(id: Int) : Entity(id) { override fun describe(): String = "User #$id" }. Here Entity is open; UserEntity extends it and overrides describe. The assignment val e: Entity = UserEntity(42) gives polymorphism; e.describe() calls the subclass's version.
Practice Write Entity + UserEntity
Define open class Entity(val id: Int) with open fun describe(): String = "Entity #${'$'}id". Define class UserEntity(id: Int) : Entity(id) with override fun describe(): String = "User #${'$'}id". In main, write val e: Entity = UserEntity(42) and println(e.describe()).
Starter code
// add the Entity and UserEntity classes
fun main() {
// print the polymorphic call
}Sample solution
open class Entity(val id: Int) {
open fun describe(): String = "Entity #$id"
}
class UserEntity(id: Int) : Entity(id) {
override fun describe(): String = "User #$id"
}
fun main() {
val e: Entity = UserEntity(42)
println(e.describe())
}Expected output
User #42
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 Why is all-open used?
- To make a class final
- To add an annotation
- To open a class for a CGLIB proxy Correct answer
- To delete the IR
Explanation: Frameworks like Spring need a class to be open for a proxy.
2 Add the open keyword
____ class Entity(val id: Int) {
open fun describe(): String = "Entity #$id"
}
open class Entity(val id: Int) {
open fun describe(): String = "Entity #$id"
}
Explanation: open lets a class be subclassed.
3 Match all-open parts
| Term | Meaning |
|---|---|
open |
Enables inheritance |
override |
Overrides a method |
@Configuration |
Spring annotation |
CGLIB |
Proxy library |