1

我有3个项目:

  • 框架
  • 产品-a
  • 产品-b

每个产品都依赖于框架,但它们彼此并不认识。

我有 3 个 spring 配置文件:每个项目一个。每个产品的配置文件包括(带有<import resource="classpath:/...)框架的配置文件。

在框架中有一个名为“manager”的bean,它有一个属性List<AnInterface> theList。“管理器”有一个 addXxx(anImplementation),它将元素添加到列表中)。

框架和每个产品都提供了 的实现AnInterface,必须添加到theList.

所以最后,当产品-a 运行时,管理器包含来自框架的实现,以及来自产品-a,产品-b 的同上

使用 Spring 执行此初始化的最佳实践是什么?

我能想到的唯一解决方案是创建一个专用类,构造函数将获取管理器和贡献列表,并将它们添加到管理器,但这很丑,因为 1/ 它在构造函数中操作外部对象,2/ 我有创建一个虚拟类只是为了初始化其他类......我不喜欢那样。

4

2 回答 2

2

我认为如果不是真的需要,代码不应该知道 Spring。因此我会在 Spring 配置中进行所有初始化。

我们可以使用bean 定义继承和属性覆盖来做到这一点。

框架类

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>

产品 A 上下文

<bean id="managerA"
      parent="manager"
      scope="singleton"
      lazy-init="false">
    <property name="theList">
        <list>
            <ref bean="impl1"/>
            <ref bean="impl2"/>
        </list>    
    </property>
</bean>

注意此类配置中的父子属性。并不是所有的都是从父母那里继承来的。Spring文档指定:

其余的设置总是取自子定义:依赖、自动装配模式、依赖检查、单例、作用域、惰性初始化。

此外,在 Spring 中也有集合合并,因此通过在子 bean 中指定

<list merge="true">

您可以合并父列表和子列表。


我在一些项目和一些基于 Spring 的可扩展 Web 框架中观察到了这种模式。

于 2013-07-08T19:03:04.730 回答
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>
于 2013-07-08T19:47:52.717 回答