Springboot not replacing environment variables in application.properties file

試著忘記壹切 提交于 2021-01-28 07:59:02

问题


I am trying to run Quartz Scheduler using SpringBoot. Using Quartz Jdbc Data Store. Due to security reasons , we wish to pick the Db credentials from the properties file. From what I understand from here(Using env variable in Spring Boot's application.properties) and springBoot docs, SpringBoot automatically replaces environment variables in application.properties but I am not seeing this . Here is my system environment file which i am sourcing before running the application

export DB_HOST=localhost
export DB_PORT=11111
export DB_USER=root
export DB_PASSWORD=root
export QUARTZ_DB_NAME=quartz

And here is my application.properties

org.quartz.dataSource.quartzDataSource.URL =jdbc:mysql://${DB_HOST}:${DB_PORT}/${QUARTZ_DB_NAME}
org.quartz.dataSource.quartzDataSource.user = ${DB_USER}
org.quartz.dataSource.quartzDataSource.password = ${DB_PASSWORD}

And my configuration class

@Configuration
public class ConfigureQuartz {

@Autowired
private ApplicationContext applicationContext;

@Bean
public SchedulerFactoryBean schedulerFactoryBean() throws IOException
{
    final SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();
    quartzScheduler.setSchedulerName("mdsScheduler");

    quartzScheduler.setQuartzProperties(quartzProperties());
    final AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    quartzScheduler.setJobFactory(jobFactory);
    return quartzScheduler;
}



 @Bean
 public Properties quartzProperties() throws IOException {
  final PropertiesFactoryBean propertiesFactoryBean = new PropertiesFactoryBean();
  propertiesFactoryBean.setLocation(new ClassPathResource("/application.properties"));
  propertiesFactoryBean.afterPropertiesSet();
  return propertiesFactoryBean.getObject();

}

But when i run my spring application using java -jar <>.java , I dont see the values substitued .

I can workaround by reading the values using System.getEnv() but would be great if the values can be substitued . Not sure why its not working :(


回答1:


Spring-boot allows us several methods to provide externalized configurations , you can try using application.yml or yaml files instead of the property file and provide different property files setup according to different environments.We can separate out the properties for each environment into separate yml files under separate spring profiles.Then during deployment you can use :

java -jar -Drun.profiles=SpringProfileName

to specify which spring profile to use.Note that the yml files should be name like

application-{environmentName}.yml

for them to be automatically taken up by springboot. Reference : https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-properties

To read from the application.yml or property file :

The easiest way to read a value from the property file or yml is to use the spring @value annotation.Spring automatically loads all values from the yml to the spring environment , so we can directly use those values from the environment like :

@Component
public class MyBean {

    @Value("${name}")
    private String name;

    // ...

}

Or another method that spring provides to read strongly typed beans is as follows:

YML

acme:
    remote-address: 192.168.1.1
    security:
        username: admin
        roles:
          - USER
          - ADMIN

Corresponding POJO to read the yml :

@ConfigurationProperties("acme")
public class AcmeProperties {

    private boolean enabled;

    private InetAddress remoteAddress;

    private final Security security = new Security();

    public boolean isEnabled() { ... }

    public void setEnabled(boolean enabled) { ... }

    public InetAddress getRemoteAddress() { ... }

    public void setRemoteAddress(InetAddress remoteAddress) { ... }

    public Security getSecurity() { ... }

    public static class Security {

        private String username;

        private String password;

        private List<String> roles = new ArrayList<>(Collections.singleton("USER"));

        public String getUsername() { ... }

        public void setUsername(String username) { ... }

        public String getPassword() { ... }

        public void setPassword(String password) { ... }

        public List<String> getRoles() { ... }

        public void setRoles(List<String> roles) { ... }

    }
}

The above method works well with yml files.

Reference: https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html

To read from the environment :

If you are running the application on linux set the env as below :

export DB_HOST=localhost
export DB_PORT=11111
export DB_USER=root
export DB_PASSWORD=root
export QUARTZ_DB_NAME=quartz

if you are on windows set it like :

SET DB_HOST=localhost
SET DB_PORT=11111
SET DB_USER=root
SET DB_PASSWORD=root
SET QUARTZ_DB_NAME=quartz

In your application.properties if you keep the keys as below , it should automatically resolve the value from the environment :

spring.datasource.url = ${DB_HOST}/"nameofDB"
spring.datasource.username = ${DB_USER}
spring.datasource.password = ${DB_PASSWORD}


来源:https://stackoverflow.com/questions/45216494/springboot-not-replacing-environment-variables-in-application-properties-file

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!