Spring-applicationContext getBeansWithAnnotation方法返回一个空列表

时间:2018-12-29 10:12:19

标签: java spring spring-annotations

我的问题是关于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列表。

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

谢谢

1 个答案:

答案 0 :(得分:0)

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

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

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

顺便说一句:由于@MyCustomAnnotation也用@Component标记,因此默认情况下它会被Spring拾取,而无需设置include-filter