Add 'fromApplication' and 'with' Kotlin extension functions
Update `SpringApplicationExtensions.kt` with `fromApplication` and `with` functions that make `SpringApplication.from(...)` easier to use with Kotlin. Fixes gh-35756
This commit is contained in:
parent
ff35ed4be1
commit
1669b81af7
|
|
@ -16,12 +16,8 @@
|
|||
|
||||
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.launch.main as myApplicationMain
|
||||
import org.springframework.boot.fromApplication
|
||||
|
||||
object Main {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
SpringApplication.from(::myApplicationMain).run(*args)
|
||||
}
|
||||
fun main(args: Array<String>) {
|
||||
fromApplication<MyApplication>().run(*args)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,12 +16,9 @@
|
|||
|
||||
package org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test
|
||||
|
||||
import org.springframework.boot.SpringApplication
|
||||
import org.springframework.boot.docs.features.testing.testcontainers.atdevelopmenttime.test.main as myApplicationMain
|
||||
import org.springframework.boot.fromApplication
|
||||
import org.springframework.boot.with
|
||||
|
||||
object Main {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
SpringApplication.from(::myApplicationMain).with(MyContainersConfiguration::class.java).run(*args)
|
||||
}
|
||||
}
|
||||
fun main(args: Array<String>) {
|
||||
fromApplication<MyApplication>().with(MyContainersConfiguration::class).run(*args)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@
|
|||
package org.springframework.boot
|
||||
|
||||
import org.springframework.context.ConfigurableApplicationContext
|
||||
import org.springframework.util.Assert
|
||||
import org.springframework.util.ClassUtils
|
||||
import org.springframework.util.ReflectionUtils
|
||||
import kotlin.reflect.KClass
|
||||
import kotlin.reflect.KType
|
||||
|
||||
/**
|
||||
* Top-level function acting as a Kotlin shortcut allowing to write
|
||||
|
|
@ -40,3 +45,34 @@ inline fun <reified T : Any> runApplication(vararg args: String): ConfigurableAp
|
|||
*/
|
||||
inline fun <reified T : Any> runApplication(vararg args: String, init: SpringApplication.() -> Unit): ConfigurableApplicationContext =
|
||||
SpringApplication(T::class.java).apply(init).run(*args)
|
||||
|
||||
/**
|
||||
* Top-level function acting as a Kotlin shortcut allowing to write
|
||||
* `fromApplication<MyApplication>().with(...)`. This method assumes that
|
||||
* the `main` function is declared in the same file as `T`.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.1
|
||||
*/
|
||||
inline fun <reified T : Any> fromApplication(): SpringApplication.Augmented {
|
||||
val type = T::class
|
||||
val ktClassName = type.qualifiedName + "Kt"
|
||||
try {
|
||||
val ktClass = ClassUtils.resolveClassName(ktClassName, type.java.classLoader)
|
||||
val mainMethod = ReflectionUtils.findMethod(ktClass, "main", Array<String>::class.java)
|
||||
Assert.notNull(mainMethod, "Unable to find main method")
|
||||
return SpringApplication.from { ReflectionUtils.invokeMethod(mainMethod!!, null, it) }
|
||||
} catch (ex: Exception) {
|
||||
throw IllegalStateException("Unable to use 'fromApplication' with " + type.qualifiedName)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension function that allows `SpringApplication.Augmented.with` to work with Kotlin classes.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @since 3.1.1
|
||||
*/
|
||||
fun SpringApplication.Augmented.with(type: KClass<*>): SpringApplication.Augmented {
|
||||
return this.with(type.java)!!
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@
|
|||
package org.springframework.boot
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.assertj.core.api.Assertions.assertThatIllegalStateException
|
||||
import org.junit.jupiter.api.Test
|
||||
|
||||
import org.springframework.beans.factory.getBean
|
||||
import org.springframework.boot.kotlinsample.TestKotlinApplication
|
||||
import org.springframework.boot.web.servlet.server.MockServletWebServerFactory
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
|
@ -67,6 +69,18 @@ class SpringApplicationExtensionsTests {
|
|||
assertThat(environment).isEqualTo(context.environment)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Kotlin fromApplication() top level function`() {
|
||||
val context = fromApplication<TestKotlinApplication>().with(ExampleWebConfig::class).run().applicationContext
|
||||
assertThat(context.getBean<MockServletWebServerFactory>()).isNotNull
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Kotlin fromApplication() top level function when no main`() {
|
||||
assertThatIllegalStateException().isThrownBy { fromApplication<ExampleWebConfig>().run() }
|
||||
.withMessage("Unable to use 'fromApplication' with org.springframework.boot.SpringApplicationExtensionsTests.ExampleWebConfig")
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
internal open class ExampleWebConfig {
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,11 @@
|
|||
package org.springframework.boot.kotlinsample
|
||||
|
||||
import org.springframework.boot.runApplication
|
||||
import org.springframework.context.annotation.Configuration
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
open class TestKotlinApplication
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
runApplication<TestKotlinApplication>(*args)
|
||||
}
|
||||
Loading…
Reference in New Issue