从 Spring 中的“组合注释”中获取值

Posted

技术标签:

【中文标题】从 Spring 中的“组合注释”中获取值【英文标题】:Get values from 'composed Annotations' in Spring 【发布时间】:2019-05-27 13:29:17 【问题描述】:

使用 Spring,您可以拥有某种组合注释。一个突出的例子是@SpringBootApplication-annotation,它是@Configuration@EnableAutoConfiguration@ComponentScan的组合。

我正在尝试获取受某个注释影响的所有 Bean,即ComponentScan

按照this 的回答,我正在使用以下代码:

for (T o : applicationContext.getBeansWithAnnotation(ComponentScan.class).values()) 
    ComponentScan ann = (ComponentScan) o.getClass().getAnnotation(ComponentScan.class);
    ...

这不起作用,因为并非所有由 getBeansWithAnnotation(ComponentScan.class) 返回的 bean 确实都使用该注释进行了注释,因为那些是例如带有@SpringBootApplication 注释的(通常)不是。

现在我正在寻找某种通用方式来检索注释的值,即使它只是作为另一个注释的 piece 添加。 我该怎么做?

【问题讨论】:

【参考方案1】:

事实证明,有一个实用程序集AnnotatedElementUtils 允许您处理那些合并的注释

for (Object annotated : context.getBeansWithAnnotation(ComponentScan.class).values()) 
    Class clazz = ClassUtils.getUserClass(annotated) // thank you jin!
    ComponentScan mergedAnnotation = AnnotatedElementUtils.getMergedAnnotation(clazz, ComponentScan.class);
    if (mergedAnnotation != null)  // For some reasons, this might still be null.
        // TODO: useful stuff.
    

【讨论】:

【参考方案2】:

它可能是 CglibProxy。所以不能直接获取Annotation。

ClassUtils.isCglibProxyClass(o)

更多信息请参见this


编辑,你可以添加你的逻辑代码。找到 ComponentScan。

if (ClassUtils.isCglibProxyClass(o.getClass())) 
            Annotation[] annotations = ClassUtils.getUserClass(o).getAnnotations();
            for (Annotation annotation : annotations) 
                ComponentScan annotation1 = annotation.annotationType().getAnnotation(ComponentScan.class);
// in my test code , ComponentScan can get here.for @SpringBootApplication 
                System.out.println(annotation1);
            

        

【讨论】:

你猜对了,它是一个CglibProxyClass。但是注释ComponentScan 也不存在于ClassUtils.getUserClass(o) - @SpringBootApplication 存在于两个类中,ClassUtils.getUserClass(o)o.getClass() 我相信你有 2 个选择,#1 知道所有使用 ComponentScan 注释的 Annotations。从您最初的了解来看,SpringBootApplication 就是其中之一。因此,如果您发现该类被注释了,并且其余的组合注释(希望 spring 有文档),那么您知道该类使用“硬编码”注释列表具有 ComponentScan。另一种方法是(#2)找到不是ComponentScan的注解的ComponentScan注解。例如,这是真的: SpringBootApplication.class.isAnnotationPresent(ComponentScan.class) @jin,所以你基本上建议,递归地爬过树,编写注释来找到我要找的那个。这似乎可行,但我还无法检索关联的值。然而,它指向了正确的方向,只是有点复杂。看来,这些值并没有真正设置,所以我必须检查 annotations 方法,用 AliasFor.class 注释来找到我必须读取的值。 是的,这很复杂。我想在 BeanDefinition 中获取一些信息的另一种方式。但它也很复杂。

以上是关于从 Spring 中的“组合注释”中获取值的主要内容,如果未能解决你的问题,请参考以下文章

我无法从 laravel 中的输入值中获取请求值

从下拉列表 Select2 中的多个值中获取选定值

无法从 VS2019 中的 Boost 属性树映射值中获取值()

如何从Java中的字符串值中获取枚举值

ClearML 从记录的值中获取最大值

如何从值中获取“captureDate”并将其作为消息发送