【问题标题】:Spring @AliasFor not working for @Profile annotationSpring @AliasFor 不适用于 @Profile 注释
【发布时间】:2021-11-15 17:24:29
【问题描述】:

环境:Kotlin 1.5.30、SpringBoot 2.5.4(Spring 5.3.9)

背景与问题

我正在尝试创建一个组合注释来简化类似的模板注释代码。注解类是这样的:

@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 属性中指定默认值,而不是在注释上,当然保留确实需要为 RUNTIME 否则不会一起被检测到。
  • @M.Deinum 感谢您的评论,但是 1)在 Kotlin 中,运行时保留是 enabled by default,所以我们可以显式添加 RUNTIME 但没关系。 2)我尝试在profiles attr 中添加默认值,但由于上述2个恼人的异常,仍然需要在@Profile 注释中传递值。
  • 哪个?正如您所说的 3 个错误... @Profile 也需要在那里但为空。可能是 Kotlin 正在扔东西,但它应该“正常工作(tm)”......
  • @M.Deinum 不,我相信它一定是弹簧错误而不是 Kotlin,因为 java.lang.IllegalArgumentException: Must specify at least one profile 堆栈跟踪只是 at org.springframework.core.env.ProfilesParser.parse(ProfilesParser.java:46) ~[spring-core-5.3.9.jar:5.3.9]
  • 这实际上让我想知道 @AliasFor 在用作组合注释时是否支持@Profile。对于 Kotlin 部分,我想知道 Kotlin 是否删除/添加了一些内容,这使得阅读组合注释变得困难/不可能(因此提示 Kotlin)。

标签: spring spring-boot kotlin annotations


【解决方案1】:

@Profile 由org.springframework.context.annotation.ProfileCondition 查找,其matches(...) 方法使用org.springframework.core.type.AnnotatedTypeMetadata.getAllAnnotationAttributes(String) 查找@Profile 注释,该方法的Javadoc 声明如下(粗体强调由我添加)。

检索给定类型的所有注释的所有属性,如果有的话(即,如果在底层元素上定义,作为直接注释或元注释)。 请注意,此变体不考虑属性覆盖。

因此,您目前不能将@Profile 与@AliasFor 一起用于注释属性覆盖。

【讨论】:

    猜你喜欢
    • 2015-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2016-05-01
    • 2019-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多