java - 使用 PropertySourcesPlaceholderConfigurer 时如何解密属性值

标签 java spring properties jasypt

我有一个包含值的属性文件,如 jdbc.password={enc}laksksjdjdj

使用 JDK 1.7 和 Spring 4.1.5 我的配置类如下所示

@PropertySources({
    @PropertySource("classpath:application.properties"),
    @PropertySource("classpath:env.properties")
})
@ComponentScan("com.acme")
@Configuration
public class SpringConfig
{
    @Autowired
    private ConfigurableEnvironment env;    

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
    {
        return new EncryptedPropertySourcesPlaceholderConfigurer();
    }
}

我想要实现的是将我的属性文件中的任何值从加密值转换为实际值。有些值将被加密,有些则不会。这是我到目前为止所尝试的,当我在 convertProperties() 上放置断点时,props 参数始终为空。我无法理解这一点,因为我可以看到此时 this.environment 加载了文件中的所有属性。

public class EncryptedPropertySourcesPlaceholderConfigurer extends PropertySourcesPlaceholderConfigurer
{
    @Override 
    protected void convertProperties(Properties props)
    {
        Enumeration<?> propertyNames = props.propertyNames();

        while (propertyNames.hasMoreElements()) {

            String propertyName = (String) propertyNames.nextElement(); 
            String propertyValue = props.getProperty(propertyName); 

            // String convertedValue = <translate the value>;

            props.setProperty(propertyName, convertedValue);
        } 
    }

    @Override
    protected Properties mergeProperties() throws IOException {
        final Properties mergedProperties = super.mergeProperties();
        convertProperties(mergedProperties);
        return mergedProperties;
    }
}

有没有人能够使用 PropertySourcesPlaceholderConfigurer 实现此目的?我在使用 PropertyPlaceholderConfigurer 的旧应用程序中有类似的逻辑,但我想使用较新的 Spring 配置。

我注意到 Jasypt 有一个类似的 EncryptablePropertySourcesPlaceholderConfigurer 但它的行为方式相同,所以我很困惑。

最佳答案

由于某些原因,使用 @PropertySources 注释无法按预期工作。

当调用 EncryptedPropertySourcesPlaceholderConfigurer.convertProperties() 时, Autowiring 的 ConfigurableEnvironment 不包含我的属性文件中的条目。根本没有对我列出的属性文件的引用。

为了解决这个限制,我删除了注释并在配置类中显式加载了这些资源。所以它现在读起来是这样的

@ComponentScan("com.acme")
@Configuration
public class SpringConfig
{ 
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer()
    {
        EncryptedPropertySourcesPlaceholderConfigurer p = new EncryptedPropertySourcesPlaceholderConfigurer(new KeyfileDecryptor());
        p.setLocations(
                new ClassPathResource("application.properties"),
                new ClassPathResource("env.properties")
                );
        return p;
    }

    @Bean
    public DataSource dataSource(
            @Value("${jdbc.driverclassname}") String driverclassname,
            @Value("${jdbc.url}") String url,
            @Value("${jdbc.username}") String username,
            @Value("${jdbc.password}") String password)
    {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();

        dataSource.setDriverClassName(driverclassname);
        dataSource.setUrl(url);
        dataSource.setUsername(username);
        dataSource.setPassword(password);

        return dataSource;
    }
}

此更改引入了 Autowiring 的 ConfigurableEnvironment 将为 null 的问题,因此我不得不更改为使用 @Value 注入(inject)以进行配置我的 dataSource 来自属性。

现在一切都按预期工作,EncryptedPropertySourcesPlaceholderConfigurer.convertProperties() 从两个文件中接收所有属性值。

关于java - 使用 PropertySourcesPlaceholderConfigurer 时如何解密属性值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30088817/

相关文章:

java - Android保存backstack fragment历史

Springframwork 和 Elasticsearch 动态字段\属性名称

java - 由于后台线程,tomcat 无法重新加载上下文

java - 在 Spring MVC 中排除 JSON 中的属性(在 Jackson 序列化期间)

excel - 具有属性的 VBA 类

java - 必须在 CamelContext 中定义具有名称属性的 PropertiesComponent 以支持属性占位符

对本地 apache 服务器的 Java http 请求 - UnknownHostException

java - 解释泛型如何在此方法中工作

java - 集合的唯一性

c# - 属性 setter 中的 StackOverflowException