3

我正在尝试使我的应用程序向后兼容至少一个以前的版本。我遇到的最大问题是旧属性文件中不存在的预期属性。

例如,假设旧的属性文件如下所示:

prop.old=some text

新的属性文件如下所示:

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

新的 app-context.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>

显然,这将在运行时爆炸。有没有办法检查属性是否存在,如果不存在,则使用空字符串代替?

4

2 回答 2

2

从 3.0 开始,您可以在PropertyPlaceholderConfigurer

<context:property-placeholder ignore-unresolvable="true" />
于 2012-10-18T19:23:06.743 回答
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(String key) 将返回 null。

于 2012-10-18T23:27:31.370 回答