2015-07-24 2 views
2

Мы настраиваем новое приложение 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 
+0

Можете ли вы попробовать использовать 'classpath:' вместо 'file:'? для '@ PropertySource' –

+0

Ну,' @ PropertySource' - это не тот объект, из которого в этом случае должны исходить свойства. Свойства, которые мы хотим, должны поступать из 'PropertySourcesPlaceholderConfigurer' 'Bean', который был создан в' BaseConfig'. '@ PropertySource' работает по назначению, если это имеет значение. Мы используем свойства, полученные позже в методе' dataSource'. –

+0

Но вы не должны отправлять все эти свойства в одном проекте или, по крайней мере, это не распространено.Возможно, вам захочется загрузить одно имя файла и настроить базу beans на фактический профиль Spring. Взгляните на [это] (https://bitbucket.org/vadimvera/spring-mvc/) –

ответ

0

Так это выглядит, как я делаю это все неправильно. Я пошел по верному пути, но потом почему-то свалился с рельсов. Правильный способ сделать это, чтобы иметь @Configuration классы для каждой среды и имеют каждый пункт различных application.properties файлов:

@Configuration 
@Profile("development") 
@PropertySource("classpath:development/application.properties") 
public class DevelopmentConfig extends BaseConfig { 
} 

И:

@Configuration 
@Profile("production") 
@PropertySource("classpath:production/application.properties") 
public class ProductionConfig extends BaseConfig { 
} 

Затем, необходимо указать профиль, который будет использоваться на в командной строке при запуске сервера:

-Dspring.profiles.active="development" 
Смежные вопросы