Browse Source

Add AOT/Native support

This commit adds AOT/Native support for beans that are contributed by
the Kotlin DSL.

Since they use an instance supplier, such beans are now configured to
be ignored by AOT generation. They are part of the bean factory still
so any hint generation works.

This commit removes a previous attempt at fixing this issue when we
were not checking for instance suppliers. Rather than skipping the
initializr at runtime, it runs again as intended since their state
can't be stored in AOT-generated code.

Closes gh-29555
pull/33277/head
Stéphane Nicoll 2 years ago
parent
commit
b8f9913aa1
  1. 9
      spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt
  2. 20
      spring-context/src/test/kotlin/org/springframework/context/support/BeanDefinitionDslTests.kt

9
spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2024 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -16,8 +16,8 @@ @@ -16,8 +16,8 @@
package org.springframework.context.support
import org.springframework.aot.AotDetector
import org.springframework.beans.factory.ObjectProvider
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor
import org.springframework.beans.factory.config.BeanDefinition
import org.springframework.beans.factory.config.BeanDefinitionCustomizer
import org.springframework.beans.factory.getBeanProvider
@ -191,6 +191,7 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit @@ -191,6 +191,7 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit
description?.let { bd.description = description }
role?.let { bd.role = role.ordinal }
order?.let { bd.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, order) }
bd.setAttribute(BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE, true)
}
val beanName = name ?: BeanDefinitionReaderUtils.uniqueBeanName(T::class.java.name, context);
@ -237,6 +238,7 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit @@ -237,6 +238,7 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit
description?.let { bd.description = description }
role?.let { bd.role = role.ordinal }
order?.let { bd.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, order) }
bd.setAttribute(BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE, true)
}
@ -1199,9 +1201,6 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit @@ -1199,9 +1201,6 @@ open class BeanDefinitionDsl internal constructor (private val init: BeanDefinit
* @param context The `ApplicationContext` to use for registering the beans
*/
override fun initialize(context: GenericApplicationContext) {
if (AotDetector.useGeneratedArtifacts()) {
return
}
this.context = context
init()
for (child in children) {

20
spring-context/src/test/kotlin/org/springframework/context/support/BeanDefinitionDslTests.kt

@ -21,6 +21,7 @@ import org.assertj.core.api.Assertions.assertThatExceptionOfType @@ -21,6 +21,7 @@ import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.jupiter.api.Test
import org.junit.jupiter.api.fail
import org.springframework.beans.factory.NoSuchBeanDefinitionException
import org.springframework.beans.factory.aot.BeanRegistrationAotProcessor
import org.springframework.beans.factory.getBean
import org.springframework.beans.factory.getBeanProvider
import org.springframework.context.support.BeanDefinitionDsl.*
@ -217,6 +218,25 @@ class BeanDefinitionDslTests { @@ -217,6 +218,25 @@ class BeanDefinitionDslTests {
assertThat(context.getBeanProvider<FooFoo>().orderedStream().map { it.name }).containsExactly("highest", "lowest")
}
@Test
fun `Declare beans with the functional Kotlin DSL flag them as to be ignored by AOT`() {
val beans = beans {
bean<Foo>("one")
bean<Bar>("two")
}
val context = GenericApplicationContext().apply {
beans.initialize(this)
}
assertThat(context.beanDefinitionNames).contains("one", "two")
assertThat(context.getBeanDefinition("one").getAttribute(
BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE)).isEqualTo(true)
assertThat(context.getBeanDefinition("two").getAttribute(
BeanRegistrationAotProcessor.IGNORE_REGISTRATION_ATTRIBUTE)).isEqualTo(true)
}
}
class Foo

Loading…
Cancel
Save