如何在Spring应用程序上下文中扩展已定义的列表和映射?

想象一下具有不同阶段的分阶段应用程序上下文。 我们从早期阶段开始,定义必要的基础设施。 xml应用程序上下文按顺序加载。

拆分这些文件的原因是扩展/插件机制。

阶段01-default-configuration.xml

我们准备并使用id exampleMapping声明地图,以便稍后使用数据增强它们。

    

阶段02-custom-configuration.xml (可选)

我们配置exampleMapping并添加一个条目。

      

阶段03-make-use-of-configuration.xml (必填)

使用定义的map exampleMapping ,无论是自定义配置还是仍然是空的声明映射。

      

这里的问题是,在第一阶段之后无法向exampleMapping地图添加条目。 Spring抛出了一个exception,即带有id exampleMapping的映射已经存在。 如果我们省略第一阶段,则地图未声明,第三阶段无法解析exampleMapping ,这也会产生exception。

我该如何解决这个问题? 我阅读了Collection merge (spring docs),但这并没有帮助。 是否可以在使用之前将值添加到地图/列表中?

谢谢!

可以定义exampleMapping是第二个定义在一个单独的文件中,你使用将一个文件导入到另一个文件中,但这是一个脆弱的方法,很容易被破坏。

我建议采用更强大的策略。 将exampleMapping替换为Registry类,后者又包含并管理映射:

 public MappingRegistry { private final Map mappings = new HashMap(); public void addMapping(K key, V value) { mappings.put(key, value); } public Map getMappings() { return Collections.unmodifiableMap(mappings); } } 

然后,编写一个用注册表注册映射的类:

 public class MappingRegistrar { private final MappingRegistry registry; private K key; private V value; @Autowired public MappingRegistrar(MappingRegistry registry) { this.registry = registry; } public void setKey(K key) { this.key = key; } public void setValue(V value) { this.value = value; } @PostConstruct public void registerMapping() { registry.addMapping(key, value); } } 

你的配置变成这样:

     

这些映射现在可以以您认为合适的任何方式分散在整个配置中,并且它们将自行组装。 然后使用MappingRegistry注入ExampleServcie并相应地提取映射。

这比你已经拥有的工作多一点,但它更灵活,更不容易出错。 如果您正在尝试构建某种可扩展的框架,那么这一点尤其有用; 你想减少人们如何使用它的限制。

maplist都有一个名为merge=true|false属性,用于合并两个列表。 或者,您可以使用MethodInvokingFactoryBean来调用已定义的列表的add方法,以便稍后添加额外的项目。

让我们回顾一下你的例子。

1)首先使用MethodInvokingFactoryBean进行第二个场景。 我没有定义你的方式,而是以不同的方式定义了你的bean。

           

在另一个应用程序内容文件中,您可以执行以下操作来扩展地图。

             

2)现在是第一个场景。 对于这个,我刚刚在http://forum.springsource.org/showthread.php?t=53358上找到了一些东西。

               

希望能帮助到你。