From 0ad9349d84a725dc37499bcb0ed2aad0de770c73 Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Tue, 5 Feb 2019 16:54:29 +0100 Subject: [PATCH] Limit ref() and provider() visibility in Kotlin DSL This commit makes ref() and provider() only available from inside the bean lambda and not from the root level of the beans DSL. Closes gh-22177 --- .../context/support/BeanDefinitionDsl.kt | 48 +++++++++++-------- 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt b/spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt index 31b0255412..6cff53c8dd 100644 --- a/spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt +++ b/spring-context/src/main/kotlin/org/springframework/context/support/BeanDefinitionDsl.kt @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -83,7 +83,7 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit, internal val children = arrayListOf() /** - * @see provider + * @see BeanSupplierContext */ @PublishedApi internal lateinit var context: GenericApplicationContext @@ -217,7 +217,7 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit, destroyMethodName: String? = null, description: String? = null, role: Role? = null, - crossinline function: () -> T) { + crossinline function: BeanSupplierContext.() -> T) { val customizer = BeanDefinitionCustomizer { bd -> scope?.let { bd.scope = scope.name.toLowerCase() } @@ -232,30 +232,36 @@ open class BeanDefinitionDsl(private val init: BeanDefinitionDsl.() -> Unit, val beanName = name ?: BeanDefinitionReaderUtils.uniqueBeanName(T::class.java.name, context); - context.registerBean(beanName, T::class.java, Supplier { function.invoke() }, customizer) + context.registerBean(beanName, T::class.java, Supplier { function.invoke(BeanSupplierContext(context)) }, customizer) } /** - * Get a reference to the bean by type or type + name with the syntax - * `ref()` or `ref("foo")`. When leveraging Kotlin type inference - * it could be as short as `ref()` or `ref("foo")`. - * @param name the name of the bean to retrieve - * @param T type the bean must match, can be an interface or superclass + * Limit access to `ref()` and `provider()` to bean supplier lambdas. + * @since 5.2 */ - inline fun ref(name: String? = null) : T = when (name) { - null -> context.getBean(T::class.java) - else -> context.getBean(name, T::class.java) + open class BeanSupplierContext(@PublishedApi internal val context: GenericApplicationContext) { + + /** + * Get a reference to the bean by type or type + name with the syntax + * `ref()` or `ref("foo")`. When leveraging Kotlin type inference + * it could be as short as `ref()` or `ref("foo")`. + * @param name the name of the bean to retrieve + * @param T type the bean must match, can be an interface or superclass + */ + inline fun ref(name: String? = null) : T = when (name) { + null -> context.getBean(T::class.java) + else -> context.getBean(name, T::class.java) + } + + /** + * Return an provider for the specified bean, allowing for lazy on-demand retrieval + * of instances, including availability and uniqueness options. + * @see org.springframework.beans.factory.BeanFactory.getBeanProvider + */ + inline fun provider() : ObjectProvider = context.getBeanProvider() + } - - /** - * Return an provider for the specified bean, allowing for lazy on-demand retrieval - * of instances, including availability and uniqueness options. - * @since 5.1.1 - * @see org.springframework.beans.factory.BeanFactory.getBeanProvider - */ - inline fun provider() : ObjectProvider = context.getBeanProvider() - /** * Take in account bean definitions enclosed in the provided lambda only when the * specified profile is active.