如何在Spring中注入List实例?

yan*_*kee 5 java spring spring-ioc

什么有效

假设我有一个ArrayList的spring bean定义:

<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>
Run Code Online (Sandbox Code Playgroud)

现在我可以将它注入各种bean中,例如:

@Controller
class Controller {
    @Autowired
    public Controller(ArrayList<String> availableLanguages) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

这非常有效.

怎么打破

但是,如果我稍微改变我的控制器并使用类型List而不是ArrayList这样:

@Controller
class Controller {
    @Autowired
    public Controller(List<String> availableLanguages) {
        // ...
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我获得了所有类型bean的列表,String而不是我定义的bean.但是我实际上想要将List包装到一个不可修改的List中,但只有将我的依赖项降级到列表才能实现.

到目前为止发现了解决方法

以下XML文件:

<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>
Run Code Online (Sandbox Code Playgroud)

与此控制器一起使用:

@Controller
class Controller {
    @Autowired
    public Controller(Object availableLanguages) {
        List<String> theList = (List<String>)availableLanguages;
    }
}
Run Code Online (Sandbox Code Playgroud)

虽然这有效但额外的类型演员是丑陋的.

到目前为止的调查结果

我认为Spring 4.2.5(目前最新版本)中的集合有一个特殊处理,这似乎会造成所有麻烦.当参数是扩展的接口时,它会创建特殊行为Collection.因此,我可以通过使用Object或具体实现作为参数类型来解决.

有没有办法直接将列表注入bean?怎么样?

yas*_*nth 0

使用 @Qualifier 将使用给定的限定符注入 bean。您可以命名您想要成为 Bean 的列表,这样就可以正常工作。