【问题标题】:Get values from 'composed Annotations' in Spring从 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 添加。 我该怎么做?

【问题讨论】:

    标签: java spring spring-annotations


    【解决方案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 中获取一些信息的另一种方式。但它也很复杂。
      猜你喜欢
      • 1970-01-01
      • 2022-11-28
      • 1970-01-01
      • 1970-01-01
      • 2017-04-19
      • 2020-05-18
      • 1970-01-01
      • 1970-01-01
      • 2019-04-09
      相关资源
      最近更新 更多