How can I find all beans with the custom annotation @Foo?

UPDATE: Spring 5.2 changed the behavior of context.getBeansWithAnnotation(...) and it now correctly handles beans created via factory methods. So simply use that.

Original answer


While the accepted answer and Grzegorz's answer contain approaches that will work in all cases, I found a much much simpler one that worked equally well for the most common cases.

  1. Meta-annotate @Foo with @Qualifier:

    @Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Qualifier
    public @interface Foo {
    }
    
  2. Sprinkle @Foo onto the factory methods, as described in the question:

    @Foo
    @Bean
    public IFooService service1() {
        return new SpecialFooServiceImpl();
    }
    

But it will also work on the type level:

@Foo
@Component
public class EvenMoreSpecialFooServiceImpl { ... }
  1. Then, inject all the instances qualified by @Foo, regardless of their type and creation method:

    @Autowired
    @Foo
    List<Object> fooBeans; 
    

fooBeans will then contain all the instances produced by a @Foo-annotated method (as required in the question), or created from a discovered @Foo annotated class.

The list can additionally be filtered by type if needed:

@Autowired
@Foo
List<SpecialFooServiceImpl> fooBeans;

The good part is that it will not interfere with any other @Qualifier (meta)annotations on the methods, nor @Component and others on the type level. Nor does it enforce any particular name or type on the target beans.


Use getBeansWithAnnotation() method to get beans with annotation.

Map<String,Object> beans = applicationContext.getBeansWithAnnotation(Foo.class);

Here is similar discussion.