Meta information about the class or method that is requesting an instance of a managed bean should be available when using Spring's functional bean definition DSL.
This might be the corresponding InjectionPoint
or at least the class name of the requesting instance.
One can use a Bean factory function to allow injection of Logger objects into ones Beans, e.g.:
import org.slf4j.*
import org.springframework.beans.factory.InjectionPoint
import org.springframework.context.annotation.*
@Bean
@Scope("prototype")
fun logger(injectionPoint: InjectionPoint): Logger {
return LoggerFactory.getLogger(
injectionPoint.methodParameter?.containingClass // constructor
?: injectionPoint.field?.declaringClass // or field injection
)
}
This is not possible with the functional bean definition DSL in Kotlin. Neither of the two examples down below work in the most recent version of Spring, unfortunately.
import org.slf4j.*
import org.springframework.beans.factory.InjectionPoint
import org.springframework.context.support.beans
import org.springframework.context.support.BeanDefinitionDsl.Scope.PROTOTYPE
fun beans() = beans {
bean(scope = PROTOTYPE) {
val injectionPoint = ref<InjectionPoint>()
LoggerFactory.getLogger(
injectionPoint.methodParameter?.containingClass // constructor
?: injectionPoint.field?.declaringClass // or field injection
)
}
bean(scope = PROTOTYPE) { injectionPoint: InjectionPoint ->
LoggerFactory.getLogger(
injectionPoint.methodParameter?.containingClass // constructor
?: injectionPoint.field?.declaringClass // or field injection
)
}
}
See also this unanswered question of StackOverflow.
The injection into the factory functions seems to be possible since SPR-14033 / #18605.
A minimal reproduction repository can be found on GitHub.
Run ./gradlew bootRun
or .\gradlew.bat bootRun
on Windows to reproduce the error.
Comment From: sdeleuze
Sorry for the delay. I think I am not in favor of exposing InjectionPoint
support in the functional bean DSL since it looks to me more tied to the annotation and reflection based injection, not the functional one. Mixing both would be potentially confusing.