How can I inject an instance of List in Spring?

Viewed 2176

What works

Suppose I have a spring bean definition of an ArrayList:

<bean id="availableLanguages" class="java.util.ArrayList">
    <constructor-arg>
        <bean class="java.util.Arrays" factory-method="asList">
            <constructor-arg>
                <list>
                    <value>de</value>
                    <value>en</value>
                </list>
            </constructor-arg>
        </bean>
    </constructor-arg>
</bean>

Now I can inject this into all kinds of beans, e.g. like this:

@Controller
class Controller {
    @Autowired
    public Controller(ArrayList<String> availableLanguages) {
        // ...
    }
}

This works great.

How it breaks

However if I change my controller a tiny bit and use the type List instead of ArrayList like this:

@Controller
class Controller {
    @Autowired
    public Controller(List<String> availableLanguages) {
        // ...
    }
}

Then instead I get a list of all beans of type String rather then the bean I defined. However I actually want to wrap my List into an unmodifiable List, but this will only be possible if I downgrade my dependency to a list.

So far discovered workaround

The following XML file:

<bean id="availableLanguages" class="java.util.Collections" factory-method="unmodifiableList">
    <constructor-arg>
        <bean class="java.util.Arrays" factory-method="asList">
            <constructor-arg>
                <list>
                    <value>de</value>
                    <value>en</value>
                </list>
            </constructor-arg>
        </bean>
    </constructor-arg>
</bean>

works together with this controller:

@Controller
class Controller {
    @Autowired
    public Controller(Object availableLanguages) {
        List<String> theList = (List<String>)availableLanguages;
    }
}

While this works the extra type cast is ugly.

Findings so far

I figured that there is a special handling for collections in Spring 4.2.5 (the currently most recent version) which seems to cause all the trouble. It creates special behaviour when a parameter is an interface that extends Collection. Thus I can workaround by using Object or a concrete implementation as parameter type.

Question

Is there any way to directly inject a list into a bean? How?

1 Answers
Related