[英]How can I use Spring XML configuration to set a bean property with list of all beans of a certain type?
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. “tasks”包含Simple类型的所有bean。 The problem with this is that I might forget to add a Simple bean I've configured to the list.
这个问题是我可能忘记添加一个我已配置到列表中的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配置?
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"
添加和自动装配文档 。
I would suggest writing your own FactoryBean
for creating such a list. 我建议编写自己的
FactoryBean
来创建这样的列表。 This would be reusable and then configurable using XML only. 这将是可重用的,然后仅使用XML进行配置。 The
FactoryBean
would look like 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. ;)特别是我不知道,如果通过
Simple
的Class
参数的type
属性以这种方式工作。 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. 在最坏的情况下,您必须使用
String
作为属性类型,并使用Class.forName(type)
来获取您的类。 But my guess is that Spring does this transformation for you. 但我的猜测是Spring为你做了这个转变。
EDIT Even though this solution should work, I recommend Robert Munteanu's answer. 编辑虽然这个解决方案应该有效,但我推荐Robert Munteanu的回答。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.