2013-12-16 3 views
4

Я использую AbstractAnnotationConfigDispatcherServletInitializer для настройки своего веб-приложения. У меня также есть класс @Configuration, который я использую для создания нескольких бобов. В этом классе я использую аннотацию @PropertySource для загрузки файла свойств для различных параметров (например, сведения о соединении с базой данных).Настройка активного профиля для AbstractAnnotationConfigDispatcherServletInitializer, который можно использовать с @PropertySource?

В настоящее время я использую профили Maven с задачами Ant для создания правильных файлов свойств для среды выполнения. То есть, я получаю Maven для перемещения «prod.properties» или «dev.properties» в «application.properties» (который использует класс) во время сборки. Что бы я хотел сделать, это использовать Spring-профили, чтобы устранить это. Я хотел был бы быть в состоянии сделать следующее:

@PropertySource(value = "classpath:/application-${spring.profiles.active}.properties") 

Я также хочу установить профиль без использования каких-либо XML. Поэтому мне нужно будет настроить профиль на основе наличия системного свойства. Например,

String currentEnvironment = systemProperties.getProperty("current.environment"); 
if (currentEnvironment == null) { 
    ((ConfigurableEnvironment)context.getEnvironment()).setActiveProfiles("production"); 
} else { 
    ((ConfigurableEnvironment)context.getEnvironment()).setActiveProfiles(currentEnvironment); 
} 

Я не уверен, где бы я мог это сделать. Согласно an answer связанному с этим вопросу, это можно сделать в переопределении метода createRootApplicationContext в моем классе инициализатора. Но этот ответ также зависит от загружаемых классов конфигурации перед настройкой профиля.

Является ли это тем, что я хочу сделать возможным? Если да, то как?

+0

@Charles, почему вы удалили тег [spring-3.2]? Это важно. Основной класс инициализатора не существует до 3.2. –

+1

Новые теги версии [следует избегать] (http://meta.stackexchange.com/a/85744/135887), когда тег существующей версии уже охватывает ту же область. В выдержке wiki '[spring-3]' tag wiki указано, что это для ** всех ** 3.x версий Spring. Это будет 3.2. Новые функции - это не те вещи, которые собираются разбить достаточно, чтобы строго требовать новый тег здесь. (Также имейте в виду количество вопросов для основного тега версии - менее 600. Фрагментация * плохо *.) – Charles

+1

Перечитайте свою ссылку. «Единственными вопросами, которые должны использовать тег C# -4.0, на мой взгляд, являются те вопросы, которые специально задают детали о функциях, добавленных в 4.0». - Я задаю вопрос о характеристике, характерной для 3.2_. –

ответ

6

Переопределение createRootApplicationContext или createServletApplicationContext не работало для меня. Я получал различные ошибки, такие как незаконные исключения состояния и «$ {spring.profiles.active}», которые не могут быть разрешимы. Рытье через дерево наследования для AbstractAnnotationConfigDispatcherServletInitializer я придумал следующее решение:

public class ApplicationInitializer 
    extends AbstractAnnotationConfigDispatcherServletInitializer 
{ 
    @Override 
    public void onStartup(ServletContext context) throws ServletException { 
    super.onStartup(context); 

    String activeProfile = System.getProperty("your.profile.property"); 
    if (activeProfile == null) { 
     activeProfile = "prod"; // or whatever you want the default to be 
    } 

    context.setInitParameter("spring.profiles.active", activeProfile); 
    } 
} 

Теперь вы можете создать класс конфигурации, как следующий, и он будет работать нормально:

@Configuration 
@PropertySource(value = "classpath:application-${spring.profiles.active}.properties") 
public class MyAppBeans { 
    @Autowired 
    private Environment env; 

    @Bean 
    public Object coolBean() { 
    String initParam = this.env.getProperty("cool.bean.initParam"); 
    ... 
    return coolBean; 
    } 
} 

Конечно, вы должны установить «your.profile.property» через параметры VM (-Dyour.profile.property=dev) или свойства контейнера (например, свойства контейнера Tomcat).

+0

+1 Причина, по которой я думаю, что это не сработало, заключается в том, что, хотя контексты не обновляются, метаданные класса '@ Configuration' загружаются (я тоже заглядываю в это больше). Заполнитель '@ PropertySource' не может быть разрешен, если он не был объявлен, который появляется после регистрации класса. –

+0

Прежде чем опираться на это решение, я повторно реализовал методы по умолчанию в своем переопределении, добавил в мое обнаружение профиля, установил активный профиль, зарегистрировал классы конфигурации и обновил контекст. У Весны не было ничего. –

0

Вместо

@PropertySource(value = "classpath:application-${spring.profiles.active}.properties") 

Вы также могли бы сделать

@PropertySource(value = "classpath:application.properties") 

И использовать некоторые Maven плагин, как свойства-Maven-плагин (*)

<build> 
     <plugin> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>properties-maven-plugin</artifactId> 
     <version>1.0-alpha-2</version> 
     <executions> 
      <execution> 
       <phase>generate-resources</phase> 
       <goals> 
        <goal>write-active-profile-properties</goal> 
       </goals> 
       <configuration> 
        <outputFile>src/main/resources/application.properties</outputFile> 
       </configuration> 
      </execution> 
     </executions> 
     </plugin> 
    </build> 
    <profiles> 
     <profile> 
     <id>production</id> 
     <properties> 
      <profiles>prod</profiles> 
      <propertyOne>...</propertyOne> 
      <propertyTwo>...</propertyTwo> 
     </properties> 
     </profile> 
     <profile> 
     <id>development</id> 
     <properties> 
      <profiles>dev</profiles> 
      <propertyOne>...</propertyOne> 
     </properties> 
     </profile> 
    </profiles> 

, а затем запустить

mvn <lifecycle> -P production 

Есть некоторая причина в пользу передачи активного профиля в системном свойстве вместо параметра maven?

При такой конфигурации this solution работал для меня:

@Configuration 
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer 
    { 
    protected WebApplicationContext createRootApplicationContext() { 
     WebApplicationContext context = super.createRootApplicationContext(); 
     ((ConfigurableEnvironment) context.getEnvironment()).setActiveProfiles(profiles()); 
     return context; 
    } 
     public String[] profiles() { 
      InputStream input = getClass().getClassLoader() 
        .getResourceAsStream("application.properties"); 
      Properties properties = new Properties(); 
      try { 
       properties.load(input); 
      return properties.getProperty("profiles").split(",");; 
      } catch (IOException e) { 
       e.printStackTrace(); 
       String[] defaultProfiles = {"dev"}; 
       return defaultProfiles; 
       // I really think that here we shouldn't return a default profile 
      } 

     } 
} 

(*) Это старый плагин (дата выпуска 2009), так что, может быть, мы должны найти другие, что делать ту же работу, но идея плагина для писать свойства + профили maven.

+2

Дело в том, чтобы * не * использовать сложный Maven XML. –

 Смежные вопросы

  • Нет связанных вопросов^_^