我有3个项目:
每个产品都取决于框架,但他们彼此不了解。
我有3个弹簧配置文件:每个项目一个。每个产品的配置文件包括(<import resource="classpath:/...
)框架的配置文件。
在框架中有一个名为“manager”的bean,它有一个属性List<AnInterface> theList
。 “manager”有一个addXxx(anImplementation),它将元素添加到列表中。
框架和每个产品都提供AnInterface
的实现,必须将其添加到theList
。
所以最后,当product-a运行时,管理器包含来自框架的实现,以及来自product-a,idem for product-b的实现
使用Spring执行此初始化的最佳做法是什么?
我能想到的唯一解决方案是创建一个专用类,构造函数将获取管理器和贡献列表,并将它们添加到管理器中,但它很难看,因为1 /它操纵构造函数中的外部对象,2 /我必须创建一个虚拟类来初始化其他类...我不喜欢它。
答案 0 :(得分:2)
我认为如果不是真的需要,代码不应该知道Spring。因此我会在Spring配置中进行所有初始化。
我们可以使用bean definition inheritance和属性覆盖来执行此操作。
框架类
public class Manager {
private List<AnInterface> theList;
public void init() {
// here we use list initialized by product
}
}
框架上下文
<bean id="manager"
init-method="init"
abstract="true"
class="Manager">
<property name="theList">
<list/> <!-- this will be overriden or extnded -->
</property>
</bean>
产品背景
<bean id="managerA"
parent="manager"
scope="singleton"
lazy-init="false">
<property name="theList">
<list>
<ref bean="impl1"/>
<ref bean="impl2"/>
</list>
</property>
</bean>
注意此类配置中的父级和子级属性。并非所有都是从父母继承的。 Spring文档指定:
其余设置始终取自子定义:取决于,autowire模式,依赖性检查,单例,范围,延迟初始化。
此外,Spring中还有collection merging,所以通过在子bean中指定
<list merge="true">
您可以合并父级和子级列表。
我在许多项目和一些基于Spring的可扩展Web框架中观察到了这种模式。
答案 1 :(得分:1)
我接受了Grzegorz的答案,因为它是我最初问题的一个干净的解决方案,但在这里作为替代答案,是一个技术解决方案,有助于现有bean的列表属性。
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="manager"/>
<property name="targetMethod"><value>addXxx</value></property>
<property name="arguments"><list value-type="com.xxx.AnInterface">
<value ref="impl1" />
<value ref="impl2" />
...
</list></property>
</bean>