从 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 中的“组合注释”中获取值的主要内容,如果未能解决你的问题,请参考以下文章