2012-10-18 77 views
3

我试图让我的应用程序向后兼容至少一个以前的版本。我遇到的最大问题是旧属性文件中不存在的属性。使用依赖注入时,如何忽略缺失的属性?

举例来说,假设老性文件看起来像这样:

prop.old=some text 

新的属性文件看起来是这样的:

prop.old=some text 
prop.new=some new text 

而且新的应用程序上下文的相关部分。 xml看起来像这样:

<beans:bean id="myClass" class="com.mycompany.MyClass"> 
    <beans:property name="oldThing" value="${prop.old}" /> 
    <beans:property name="newThing" value="${prop.new}" /> 
</beans:bean> 

很明显,这会在运行时炸掉。有没有办法检查属性是否存在,如果不存在,请使用空字符串?

+0

可能是的。其他DI容器提供这种功能,但我不太了解Spring。 – neontapir

回答

2

由于3.0可以用忽略,不可解析= true在PropertyPlaceholderConfigurer

<context:property-placeholder ignore-unresolvable="true" /> 
0

,因为如果试图忽略缺少的属性,你不能告诉缺少的是必修课还是选修课这是棘手的。所以我更喜欢用程序化的方式来做到这一点。

首先,有一个基类来访问任何属性文件:

public abstract class ClasspathProperties { 

    private final Environment environment; 

    public ClasspathProperties(final Environment environment, final String propertiesLocation) { 
     try { 
      final PropertySource<?> propertySource = new ResourcePropertySource(propertiesLocation); 
      verifyProperties(propertySource); 
      ((ConfigurableEnvironment) environment).getPropertySources().addFirst(propertySource); 
      this.environment = environment; 
     } catch (final IOException e) { 
      throw new IllegalStateException("reading properties from location " + propertiesLocation + " failed", e); 
     } 
    } 

    public Environment getEnvironment() { 
     return environment; 
    } 

    protected abstract void verifyProperties(PropertySource<?> propertySource); 

    protected void verifyPropertyExistence(final PropertySource<?> propertySource, final String propertyName, 
      final String propertyDescription) { 
     final Object propertyValue = propertySource.getProperty(propertyName); 
     if (propertyValue == null || "".equals(propertyValue)) { 
      throw new IllegalStateException(propertyDescription + " is not set"); 
     } 
    } 

} 

然后你就可以有一个读取指定的属性文件并设置属性之前验证:

public class ClasspathDatabaseProperties extends ClasspathProperties implements DatabaseProperties { 

    public ClasspathDatabaseProperties(final Environment environment) { 
     this(environment, "classpath:/config/db-config.properties"); 
    } 

    public ClasspathDatabaseProperties(final Environment environment, final String propertiesLocation) { 
     super(environment, propertiesLocation); 
    } 

    @Override 
    protected void verifyProperties(final PropertySource<?> propertySource) { 
     verifyPropertyExistence(propertySource, "mysql.host", "MySQL DB host"); 
     verifyPropertyExistence(propertySource, "mysql.port", "MySQL DB port"); 
     verifyPropertyExistence(propertySource, "mysql.database", "MySQL DB DB name"); 
     verifyPropertyExistence(propertySource, "mysql.username", "MySQL DB username"); 
     verifyPropertyExistence(propertySource, "mysql.password", "MySQL DB password"); 
    } 

    @Override 
    public String getHost() { 
     return getEnvironment().getProperty("mysql.host"); 
    } 

    @Override 
    public int getPortNumber() { 
     return getEnvironment().getProperty("mysql.port", Integer.class); 
    } 

    @Override 
    public String getDatabase() { 
     return getEnvironment().getProperty("mysql.database"); 
    } 

    @Override 
    public String getUsername() { 
     return getEnvironment().getProperty("mysql.username"); 
    } 

    @Override 
    public String getPassword() { 
     return getEnvironment().getProperty("mysql.password"); 
    } 

} 

的getProperty(字符串如果密钥无法解析,则返回null。