使用PropertySourcesPlaceholderConfigurer从属性文件和数据库中检索值

时间:2017-07-31 12:58:22

标签: java spring spring-boot

我是Spring Boot的新手。我试图实现一个PropertySourcesPlaceholderConfigurer配置,它将从属性文件和数据库表返回属性。这是我写的:

@Configuration
@PropertySource(value = { "classpath:application.properties" }, ignoreResourceNotFound = false)
public class SpringPropertiesConfig implements EnvironmentAware {
    private static final Logger log = LoggerFactory.getLogger(SpringPropertiesConfig.class);

    @Inject
    private org.springframework.core.env.Environment env;

    @PostConstruct
    public void initializeDatabasePropertySourceUsage() {
        MutablePropertySources propertySources = ((ConfigurableEnvironment) env).getPropertySources();

        System.out.println("propertySources : " + propertySources);
        try {
            // dataSource, Table Name, Key Column, Value Column
            DatabaseConfiguration databaseConfiguration = new DatabaseConfiguration(dataSource(),
                    "APPLICATION_CONFIGURATION", "KEY", "VALUE");

            Properties dbProps = ConfigurationConverter.getProperties(databaseConfiguration);
            PropertiesPropertySource dbPropertySource = new PropertiesPropertySource("dbPropertySource", dbProps);
            propertySources.addFirst(dbPropertySource);
        } catch (Exception e) {
            log.error("Error during database properties setup", e);
            throw new RuntimeException(e);
        }
    }

    @Bean(name = "pspc")
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
        pspc.setIgnoreUnresolvablePlaceholders(true);
        // System.out.println("propertySourcesPlaceholderConfigurer = " +
        // pspc.getAppliedPropertySources());
        return pspc;
    }

    @Bean
    public DataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
        dataSource.setDriverClassName(env.getProperty("dev.datasource.driver-class-name"));
        dataSource.setUrl(env.getProperty("dev.datasource.url"));
        dataSource.setUsername(env.getProperty("dev.datasource.username"));
        dataSource.setPassword(env.getProperty("dev.datasource.password"));
        return dataSource;
    }

    @Override
    public void setEnvironment(Environment paramEnvironment) {
        this.env = paramEnvironment;
    }
}

我发现application.properties中的属性已正确解析。

@Value("${spnego.defaultRealm}")
private String defRealm;

在这里,' defRealm'包含正确的值。但是数据库中的属性没有得到解决。

@Value("${enviromentName}")
private String envir;

如果我打印了envir的值,它会打印' $ {enviromentName}'。

在SpringPropertiesConfig类中,表正在被正确读取,并且Properties对象' dbProps'打印APPLICATION_CONFIGURATION表中的所有行。

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

谢谢M. Deinum,我按照你的建议并实施了以下内容:

public class SpringPropertiesConfig implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    public DataSource getDataSource(org.springframework.core.env.PropertySource<?> propSrc) {
        String profile = (String) propSrc.getProperty("spring.profiles.active");
        if (profile.equals("dev")) {
            BasicDataSource dataSource = new BasicDataSource();
            dataSource.setDriverClassName((String) propSrc.getProperty("dev.datasource.driver-class-name"));
            dataSource.setUrl((String) propSrc.getProperty("dev.datasource.url"));
            dataSource.setUsername((String) propSrc.getProperty("dev.datasource.username"));
            dataSource.setPassword((String) propSrc.getProperty("dev.datasource.password"));
            return dataSource;
        } else if (profile.equals("prod")) {
            JndiDataSourceLookup dataSourceLookup = new JndiDataSourceLookup();
            DataSource dataSource = dataSourceLookup
                    .getDataSource((String) propSrc.getProperty("prd.datasource.jndi-name"));
            return dataSource;
        }
        return null;
    }

    @Override
    public void initialize(ConfigurableApplicationContext ctx) {
        org.springframework.core.env.PropertySource<?> p = ctx.getEnvironment().getPropertySources()
                .get("applicationConfigurationProperties");

        DatabaseConfiguration databaseConfiguration = new DatabaseConfiguration(getDataSource(p),
                "APPLICATION_CONFIGURATION", "KEY", "VALUE");

        System.out.println("databaseConfiguration created : " + databaseConfiguration);
        Properties dbProps = ConfigurationConverter.getProperties(databaseConfiguration);
        System.out.println("dbProps=" + dbProps);
        PropertiesPropertySource dbPropertySource = new PropertiesPropertySource("dbPropertySource", dbProps);
        ctx.getEnvironment().getPropertySources().addFirst(dbPropertySource);
    }
}

但我不确定是否

org.springframework.core.env.PropertySource<?> p = ctx.getEnvironment().getPropertySources().get("applicationConfigurationProperties");

是从application.properties文件中读取的最佳方式。

上面的ApplicationContextInitializer在Spring中注册如下 -

@SpringBootApplication
public class Application extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(final SpringApplicationBuilder application) {
        return application.sources(Application.class);
    }

    public static void main(final String[] args) {
        new SpringApplicationBuilder(Application.class).initializers(new SpringPropertiesConfig()).run(args);
    }

    @Bean
    public RestTemplate restTemplate(final RestTemplateBuilder builder) {
        return builder.build();
    }
}