Мы настраиваем новое приложение Spring, и мы пытаемся прикрыть, чтобы наши свойства приложения были разными для каждой среды. Мы используем PropertySourcesPlaceholderConfigurer @Beans с @Profile в specfify, какой файл свойство использовать:Не удается найти свойство при использовании PropertySourcesPlaceholderConfigurer @Bean
public abstract class BaseConfig implements InitializingBean, DisposableBean {
private static final String LOCAL_CONFIG = "local/application.properties";
private static final String DEV_CONFIG = "development/application.properties";
private static final String STAGING_CONFIG = "staging/application.properties";
private static final String PRODUCTION_CONFIG = "production/application.properties";
@Bean
@Profile("development")
public static PropertySourcesPlaceholderConfigurer developmentPropertyPlaceholderConfigurer() {
System.out.println("config'ing dev");
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(DEV_CONFIG));
return configurer;
}
@Bean
@Profile("staging")
public static PropertySourcesPlaceholderConfigurer stagingPropertyPlaceholderConfigurer() {
System.out.println("config'ing staging");
PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
configurer.setLocation(new ClassPathResource(STAGING_CONFIG));
return configurer;
}
// and so on...
}
Добавим свойство среды в командной строке, которая, похоже, выбора этих профилей правильно:
-Dspring.profiles.active="development"
мы видим это в журналах, когда BaseConfig
сканируется:
config'ing dev
2015-07-24T15:19:09,529 {} [ContainerBackgroundProcessor[StandardEngine[Catalina]]] INFO o.s.c.s.PropertySourcesPlaceholderConfigurer - Loading properties file from class path resource [development/application.properties]
когда мы пытаемся получить имущество из одного из файлов, это не в домене @ Autowire'd Environment или в среде ApplicationContext:
@Configuration
@EnableJpaRepositories(basePackages = {
"com.myapp.jpa.domain", "com.myapp.jpa.repositories" })
@EnableTransactionManagement
@PropertySource(value = "file:/my/home/dir/db.properties", ignoreResourceNotFound = true)
public class JpaConfig extends BaseConfig {
@Autowired
Environment environment;
@Bean
public DataSource dataSource() throws SQLException {
String testProperty = environment.getProperty("test.property");
logger.info("test.property from autowired environment: " + testProperty);
ApplicationContext ctx = new GenericApplicationContext();
Environment env = ctx.getEnvironment();
boolean contains = env.containsProperty("test.property");
logger.info("Does my environment contain the 'test.property' property? " + contains);
logger.info("test.property from context: " + env.getProperty("test.property"));
// ...
}
}
Оба эти оператора печатают свойство null. Таким образом, похоже, что файл application.properties
, который я хочу прочитать, на самом деле читается, но эти свойства недоступны в Environment
. Что я делаю не так? Я подозреваю, что что-то мне не хватает, чтобы подключить компонент PropertySourcesPlaceholderConfigurer Bean после его создания.
2015-07-24T15:19:09,730 {} [ContainerBackgroundProcessor[StandardEngine[Catalina]]] INFO x.y.z.JpaConfig - test.property from autowired environment: null
2015-07-24T15:19:09,731 {} [ContainerBackgroundProcessor[StandardEngine[Catalina]]] INFO x.y.z.JpaConfig - Does my environment contain the 'test.property' property? false
2015-07-24T15:19:09,731 {} [ContainerBackgroundProcessor[StandardEngine[Catalina]]] INFO x.y.z.JpaConfig - test.property from context: null
EDIT - К сожалению. Я забыл вставить здесь, что development/application.properties
выглядит следующим образом:
test.property=from_development
EDIT - Кто-то спросил об активных профилей. Я устанавливаю их, используя свойство -D
команды Java. Если он не был установлен, правильный метод в BaseConfig не будет запущен, но он есть. Я добавил код, приведенный ниже, чтобы доказать, что активный профиль, на самом деле, будучи набор:
for (String activeProfile : environment.getActiveProfiles()) {
logger.info("active profile: " + activeProfile);
}
Который производит:
2015-07-24T16:02:48,179 {} [ContainerBackgroundProcessor[StandardEngine[Catalina]]] INFO c.d.c.c.j.JpaConfig - active profile: development
Можете ли вы попробовать использовать 'classpath:' вместо 'file:'? для '@ PropertySource' –
Ну,' @ PropertySource' - это не тот объект, из которого в этом случае должны исходить свойства. Свойства, которые мы хотим, должны поступать из 'PropertySourcesPlaceholderConfigurer' 'Bean', который был создан в' BaseConfig'. '@ PropertySource' работает по назначению, если это имеет значение. Мы используем свойства, полученные позже в методе' dataSource'. –
Но вы не должны отправлять все эти свойства в одном проекте или, по крайней мере, это не распространено.Возможно, вам захочется загрузить одно имя файла и настроить базу beans на фактический профиль Spring. Взгляните на [это] (https://bitbucket.org/vadimvera/spring-mvc/) –