使用依赖注入时,如何忽略缺少的属性?

时间:2012-10-18 16:40:24

标签: spring dependency-injection

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

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

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>

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

2 个答案:

答案 0 :(得分:2)

从3.0开始,您可以在PropertyPlaceholderConfigurer

中使用ignore-unresolvable = true
<context:property-placeholder ignore-unresolvable="true" />

答案 1 :(得分: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。