Chr*_*wes 16 java spring dependency-injection
想象一下具有不同阶段的分阶段应用程序上下文.我们从早期阶段开始,定义必要的基础设施.xml应用程序上下文按顺序加载.
拆分这些文件的原因是扩展/插件机制.
阶段01-default-configuration.xml
我们准备并声明带有id的地图,exampleMapping以便稍后使用数据来增强它们.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="[...]">
<util:map id="exampleMapping" />
</beans>
Run Code Online (Sandbox Code Playgroud)
阶段02-custom-configuration.xml (可选)
我们配置exampleMapping并添加一个条目.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="[...]">
<util:map id="exampleMapping">
<entry key="theKey" value="theValue" />
</util:map>
</beans>
Run Code Online (Sandbox Code Playgroud)
阶段03-make-use-of-configuration.xml (必填)
使用定义的地图exampleMapping,无论是自定义地配置还是仍然是空的声明地图.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="[...]">
<bean id="exampleService" class="com.stackoverflow.example.ExampleService">
<property name="mapping" ref="exampleMapping" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
这里的问题是,exampleMapping在第一阶段之后无法向地图添加条目.Spring抛出了一个异常,即id exampleMapping已经存在.如果我们遗漏第一阶段,则地图未声明,第三阶段无法解决exampleMapping,这也会产生异常.
我该如何解决这个问题?我阅读了Collection merge(spring docs),但这并没有帮助.是否可以在使用之前将值添加到地图/列表中?
谢谢!
Umu*_*kan 14
双方map并list有一个名为此属性merge=true|false用于合并两个列表.或者,您可以使用MethodInvokingFactoryBean调用已定义列表的add方法稍后添加额外的项目.
让我们回顾一下你的例子.
1)首先是第二个场景MethodInvokingFactoryBean.我没有定义你的方式,而是以不同的方式定义了你的bean.
<bean class="java.util.HashMap" id="exampleMapping">
<constructor-arg index="0">
<map>
<entry key="theKey" value="theValue"/>
</map>
</constructor-arg>
</bean>
<bean id="exampleService" class="com.stackoverflow.example.ExampleService">
<property name="mapping" ref="exampleMapping"/>
</bean>
Run Code Online (Sandbox Code Playgroud)
在另一个应用程序内容文件中,您可以执行以下操作来扩展地图.
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="exampleMapping"/>
<property name="targetMethod" value="putAll"/>
<property name="arguments">
<list>
<map id="exampleMapping">
<entry key="theKey2" value="theValue2"/>
<entry key="theKey3" value="theValue3"/>
<map>
</list>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
2)现在是第一个场景.对于这个,我刚刚在页面上找到了一些内容http://forum.springsource.org/showthread.php?t=53358
<bean id="commonData" class="A">
<property name="map">
<util:map>
<entry key="1" value="1"/>
</util:map>
</property>
</bean>
<bean id="data" class="A" parent="commonData">
<property name="map">
<util:map merge="true">
<entry key="2" value="2"/>
</util:map>
</property>
</bean>
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你.
ska*_*man 12
你可以定义exampleMapping第二个定义是在一个单独的文件中,你<import resource="..."/>用来将一个文件导入到另一个文件中,但它是一个脆弱的方法,很容易被破坏.
我建议采用更强大的策略.将类替换exampleMapping为Registry类,而类又包含并管理映射:
public MappingRegistry<K,V> {
private final Map<K,V> mappings = new HashMap<K,V>();
public void addMapping(K key, V value) {
mappings.put(key, value);
}
public Map<K,V> getMappings() {
return Collections.unmodifiableMap(mappings);
}
}
Run Code Online (Sandbox Code Playgroud)
然后,编写一个用注册表注册映射的类:
public class MappingRegistrar<K,V> {
private final MappingRegistry<K,V> registry;
private K key;
private V value;
@Autowired
public MappingRegistrar(MappingRegistry<K,V> 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);
}
}
Run Code Online (Sandbox Code Playgroud)
你的配置变成这样:
<bean id="mappingRegistry" class="com.xyz.MappingRegistry"/>
<bean id="mappingA" class="com.xyz.MappingRegistrar" p:key="keyA" p:value="valueA"/>
<bean id="mappingB" class="com.xyz.MappingRegistrar" p:key="keyB" p:value="valueB"/>
<bean id="mappingC" class="com.xyz.MappingRegistrar" p:key="keyC" p:value="valueC"/>
Run Code Online (Sandbox Code Playgroud)
这些映射现在可以以您认为合适的任何方式分散在整个配置中,并且它们将自行组装. ExampleServcie然后注入并相应地MappingRegistry提取映射.
它比你已经拥有的工作多一点,但它更灵活,更不容易出错.如果您正在尝试构建某种可扩展的框架,那么这一点尤其有用; 你想减少人们如何使用它的限制.
| 归档时间: |
|
| 查看次数: |
22621 次 |
| 最近记录: |