Ignore default list of beans created/used by @Autowired

Problem

You define a group of beans of certain type in Spring and at the same time you want to define a custom list of these beans. However when using @Autowired to inject this list you end up with the default implementation of the list provided by @Autowired .

Imagine those are the beans that we define in Spring Configuration:

Now let’s say you want to create a bean that is a list of Environments, a list of specific implementation. You might be tempted to do something like this:

Surprise, surprise, everything works! Until in some other place in the code you decide to autowire this list:

Soon enough you will find out that the list you received is not the MagicList you have been expecting.

Not working solution

My first idea was to add @Order/ @Priority when defining the list.

Well that did not work very well.

Some workarounds

An obvious workaround would be add a @Qualifier annotation so that when injecting the list be able to specify what implementation should be provided.

At the same time instead of autowiring the List interface, we could autowire particular implementation.

Both solutions would work but they somehow do not feel right – they explicitly expose specific implementation of the list. Also they seem error-prone as I can easily imagine a situation when someone forgets to put the @Qualifier annotation and ends up with wrong implementation without even realizing this fact.

Solution

To fix this problem we will do two things. First of all we will remove Environment class beans as candidates for autowiring (thanks to Marcin Grzejszczak for the tip how do to it). Thanks to that there will not be any default Listobject.

Now, let’s create our own list of Environments.

Et voilà! Now a simple @Autowired annotation will inject our custom implementation of List interface.

Sources and links

Please join discussion