首页 > 解决方案 > Spring - applicationContext getBeansWithAnnotation 方法返回一个空列表

问题描述

我的问题是关于 getBeansWithAnnotation 方法。

我有一个名为 MyCustomAnnotation 的自定义注释。

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
@Scope("prototype")
public @interface MyCustomAnnotation {

    String group() default "DEFAULT_GROUP";
}

我还有一个如下的监听器类:

public class MyCustomAnnotationListener implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        Map<String, Object> myCustomAnnotationBeans = applicationContext.getBeansWithAnnotation(MyCustomAnnotation.class);
    }
}

我已将 application-context.xml 配置为使用 MyCustomAnnotation 扫描组件。

<context:include-filter type="annotation" expression="com.annotations.MyCustomAnnotation"/>

在我的应用程序初始启动期间,我可以使用 MyCustomAnnotationListener 中的 getBeansWithAnnotation 方法获取使用 MyCustomAnnotation 注释的 bean 列表。

我的问题是为什么这个方法在第二次触发时返回一个空列表。

谢谢

标签: javaspringspring-annotations

解决方案


ContextRefreshedEvent应该在引导上下文期间发生一次。它将事件发布到上下文本身及其所有父上下文。

现在它的侦听器(即MyCustomAnnotationListener)执行 2 次,表明您的上下文可能有一个父上下文。bean@MyCustomAnnotation是在子上下文中定义的,因此父上下文找不到它,并且MyCustomAnnotationListener在为父上下文运行时返回空列表。

您可以使用 . 验证上下文是否相同applicationContext.getId()

BTW:@MyCustomAnnotation同样标有@Component,默认会被Spring拾取,无需设置include-filter


推荐阅读