问题
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