My Spring配置如下所示:
<jee:remote-slsb id="ejb1"
jndi-name="org.example.Ejb1"
business-interface="org.example.Ejb1"
environment-ref="ejb1Properties">
</jee:remote-slsb>
<util:properties id="ejb1Properties" location="classpath:ejb1.properties"/>
<jee:remote-slsb id="ejb2"
jndi-name="org.example.Ejb2"
business-interface="org.example.Ejb2"
environment-ref="ejb2Properties">
</jee:remote-slsb>
<util:properties id="ejb2Properties" location="classpath:ejb2.properties"/>
...因为两个EJB可能使用不同的JNDI URL,不同的上下文工厂和身份验证凭据。 ejb1.properties和ejb2.properties具有相同名称的属性,具有不同的值:
ejb1.properties:
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://example1:7101
java.naming.security.principal=id1
java.naming.security.credential=foo
ejb2.properties:
java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
java.naming.provider.url=t3://example2:7101
java.naming.security.principal=id2
java.naming.security.credential=bar
但是,我希望我的用户可以维护一个属性文件,而不是两个。
显然,编写一个从核心属性文件生成ejb1.properties和ejb2.properties的启动脚本很容易。但有没有办法让Spring从单个文件获取属性,适当地映射名称?
答案 0 :(得分:5)
AFAIK,Spring中没有任何东西可以处理你的情况。但是,一个直接的解决方案是扩展PropertiesFactoryBean并覆盖mergeProperties()方法。以下是基于名称前缀过滤属性条目的扩展示例:
public class FilteringPropertiesFactoryBean extends PropertiesFactoryBean {
private String namePrefix;
@Override
protected Properties mergeProperties() throws IOException {
Properties unfilteredProperties = super.mergeProperties();
Properties filteredProperties = new Properties();
// iterator over keys
// discard entries whose key doesn't start with prefix
for (Object key : unfilteredProperties.keySet()) {
String name = key.toString();
// trim the property name by removing the target prefix.
String trimmedName = trimName(name);
if (trimmedName != null) {
// add the property to the filtered collection
String value = unfilteredProperties.getProperty(name);
filteredProperties.setProperty(trimmedName, value);
}
}
return filteredProperties;
}
public void setNamePrefix(String value) {
this.namePrefix = value;
}
private String trimName(String name) {
// does name start with the prefix and is the name longer than the prefix
if (name.startsWith(namePrefix) && name.length() > namePrefix.length()) {
return name.substring(namePrefix.length());
}
return null;
}
}
配置工厂bean将类似于:
<bean id="ejb1Properties" class="example.FilteringPropertiesFactoryBean">
<property name="location" value="classpath:merged.properties"/>
<property name="namePrefix" value="ejb1."/>
</bean>
使用上面的配置和merged.properties文件包含:
ejb1.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
ejb1.java.naming.provider.url=t3://example1:7101
ejb1.java.naming.security.principal=id1
ejb1.java.naming.security.credential=foo
ejb2.java.naming.factory.initial=weblogic.jndi.WLInitialContextFactory
ejb2.java.naming.provider.url=t3://example2:7101
ejb2.java.naming.security.principal=id2
ejb2.java.naming.security.credential=bar
FilteringPropertiesFactoryBean#mergeProperties()返回的结果属性是(注意前缀从最终属性名称中删除):
java.naming.factory.initial = weblogic.jndi.WLInitialContextFactory
java.naming.provider.url = t3://example1:7101
java.naming.security.principal = id1
java.naming.security.credential = foo