Java 如何使用 Spring XML 配置来设置带有特定类型的所有 bean 列表的 bean 属性?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/943439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I use Spring XML configuration to set a bean property with list of all beans of a certain type?
提问by David Resnick
I have the following XML configuration:
我有以下 XML 配置:
<bean id="bean1" class="Simple"/>
<bean id="bean2" class="Simple"/>
<bean id="tasks" class="java.util.ArrayList">
<constructor-arg>
<list>
<ref bean="bean1" />
<ref bean="bean2" />
</list>
</constructor-arg>
</bean>
<bean id="list" class="Comp">
<property name="tasks" ref="tasks"/>
</bean>
The "tasks" contains all beans of type Simple. The problem with this is that I might forget to add a Simple bean I've configured to the list.
“任务”包含所有类型为 Simple 的 bean。这样做的问题是我可能忘记将我配置的 Simple bean 添加到列表中。
I could do this programatically using
我可以使用编程方式做到这一点
Map map = context.getBeansOfType(Simple.class);
and setting the list bean with the beans retrieved.
并使用检索到的 bean 设置列表 bean。
Is there any way of doing this using just XML configuration?
有没有办法只使用 XML 配置来做到这一点?
采纳答案by Robert Munteanu
Your context file should like this:
你的上下文文件应该是这样的:
<bean id="bean1" class="Simple"/>
<bean id="bean2" class="Simple"/>
<bean id="list" class="Comp" autowire="byType"/>
Note the autowire="byType"
addition, and the autowiring documentation.
请注意autowire="byType"
添加和自动装配文档。
回答by rudolfson
I would suggest writing your own FactoryBean
for creating such a list. This would be reusable and then configurable using XML only. The FactoryBean
would look like
我建议您自己编写FactoryBean
以创建这样的列表。这将是可重用的,然后仅使用 XML 进行配置。该FactoryBean
会是什么样子
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
public class CollectingListFactoryBean implements FactoryBean, ApplicationContextAware {
private ApplicationContext appCtx;
private Class type;
public Object getObject() {
Assert.notNull(type, "type must be initialized");
List result = new ArrayList();
result.addAll(appCtx.getBeansOfType(type).values());
return result;
}
public Class getObjectType() {
return List.class;
}
public boolean isSingleton() {
return false;
}
public void setApplicationContext(ApplicationContext applicationContext) {
this.appCtx = applicationContext;
}
public void setType(Class type) {
this.type = type;
}
}
Then your XML configuration would be
那么你的 XML 配置将是
<bean id="bean1" class="Simple"/>
<bean id="bean2" class="Simple"/>
<bean id="tasks" class="CollectingListFactoryBean">
<property name="type" value="Simple" />
</bean>
<bean id="list" class="Comp">
<property name="tasks" ref="tasks"/>
</bean>
NOTE: I didn't have the time to test the example above. I just used code I already had as a template. ;) Especially I'm not sure if passing Simple
as a Class
argument for the type
property works this way. Just give it a try. In the worst case you would have to use String
as the property type and use Class.forName(type)
to get your class. But my guess is that Spring does this transformation for you.
注意:我没有时间测试上面的例子。我只是使用我已经拥有的代码作为模板。;) 特别是我不确定Simple
作为属性的Class
参数传递是否以type
这种方式工作。试试吧。在最坏的情况下,您将不得不使用String
作为属性类型并用于Class.forName(type)
获取您的类。但我的猜测是 Spring 为您完成了这种转换。
EDITEven though this solution should work, I recommend Robert Munteanu's answer.
编辑即使这个解决方案应该有效,我还是推荐 Robert Munteanu 的回答。