Spring @AliasFor 不适用于@Profile 注释
Spring @AliasFor not working for @Profile annotation
Environment: Kotlin 1.5.30, SpringBoot 2.5.4(Spring 5.3.9)
背景与问题
我正在尝试创建一个组合注释来简化类似的模板注释代码。注解class是这样的:
@Profile("default") //NOTE 1: use a placeholder, see the investigations below
annotation class ProfileAware(
@get: AliasFor(annotation = Profile::class, attribute = "value")
val profiles: Array<String>,
//properties delegated for other annotations
)
预期用途:
@Component
@ProfileAware(profiles = ["dev"])
class TheBean {
init {
LoggerFactory.getLogger("TheBean").info("TheBean: I'm registered")
}
}
在application.yaml中:
spring:
profiles:
active: dev
但是应用启动后,TheBean没有按预期注册。
调查与尝试
首先,我在 github spring 存储库中进行了搜索,并找到了这个:Regression: custom composed @Profile annotation without runtime retention no longer supported with component scanning。所以我尝试在@ProfileAware上添加@Retention(AnnotationRetention.RUNTIME)
,但没有效果。
试图从元注释中删除 ("default")
值 (以及是否将默认值添加到 profiles
属性) , 但得到 java.lang.IllegalArgumentException: Must specify at least one profile
.
试图从元注释中删除 @Profile("default")
,但得到 AnnotationConfigurationException: @AliasFor declaration on attribute 'profile' in annotation ... which is not meta-present.
(重要) 尝试直接在 bean 上使用 @Profile("dev") 而不是 ProfileAware
,按预期工作。
(重要) 尝试将元注释上的值更改为“dev”,它有效,但显然它是硬编码的,不符合我的需要。
我做错了什么吗?或者是否可以创建具有动态 @Profile 值的组合注释?
感谢您的阅读和帮助。
@Profile
由 org.springframework.context.annotation.ProfileCondition
查找,其 matches(...)
方法使用 org.springframework.core.type.AnnotatedTypeMetadata.getAllAnnotationAttributes(String)
查找 @Profile
注释,该方法的 Javadoc 指出以下(我添加的粗体强调)。
Retrieve all attributes of all annotations of the given type, if any (i.e. if defined on the underlying element, as direct annotation or meta-annotation). Note that this variant does not take attribute overrides into account.
因此,您目前无法将 @Profile
与 @AliasFor
一起用于注释属性覆盖。
Environment: Kotlin 1.5.30, SpringBoot 2.5.4(Spring 5.3.9)
背景与问题
我正在尝试创建一个组合注释来简化类似的模板注释代码。注解class是这样的:
@Profile("default") //NOTE 1: use a placeholder, see the investigations below
annotation class ProfileAware(
@get: AliasFor(annotation = Profile::class, attribute = "value")
val profiles: Array<String>,
//properties delegated for other annotations
)
预期用途:
@Component
@ProfileAware(profiles = ["dev"])
class TheBean {
init {
LoggerFactory.getLogger("TheBean").info("TheBean: I'm registered")
}
}
在application.yaml中:
spring:
profiles:
active: dev
但是应用启动后,TheBean没有按预期注册。
调查与尝试
首先,我在 github spring 存储库中进行了搜索,并找到了这个:Regression: custom composed @Profile annotation without runtime retention no longer supported with component scanning。所以我尝试在@ProfileAware上添加
@Retention(AnnotationRetention.RUNTIME)
,但没有效果。试图从元注释中删除
("default")
值 (以及是否将默认值添加到profiles
属性) , 但得到java.lang.IllegalArgumentException: Must specify at least one profile
.试图从元注释中删除
@Profile("default")
,但得到AnnotationConfigurationException: @AliasFor declaration on attribute 'profile' in annotation ... which is not meta-present.
(重要) 尝试直接在 bean 上使用 @Profile("dev") 而不是
ProfileAware
,按预期工作。(重要) 尝试将元注释上的值更改为“dev”,它有效,但显然它是硬编码的,不符合我的需要。
我做错了什么吗?或者是否可以创建具有动态 @Profile 值的组合注释?
感谢您的阅读和帮助。
@Profile
由 org.springframework.context.annotation.ProfileCondition
查找,其 matches(...)
方法使用 org.springframework.core.type.AnnotatedTypeMetadata.getAllAnnotationAttributes(String)
查找 @Profile
注释,该方法的 Javadoc 指出以下(我添加的粗体强调)。
Retrieve all attributes of all annotations of the given type, if any (i.e. if defined on the underlying element, as direct annotation or meta-annotation). Note that this variant does not take attribute overrides into account.
因此,您目前无法将 @Profile
与 @AliasFor
一起用于注释属性覆盖。