Как установить активный профиль среды Spring 3.1 через файл свойств, а не через переменную env или системное свойство - PullRequest
49 голосов
/ 21 декабря 2011

Мы используем новую функцию профилей среды Spring 3.1. В настоящее время мы устанавливаем активный профиль, устанавливая переменную среды spring.profiles.active = xxxxx на сервере, на котором мы развертываем приложение.

Мы считаем, что это неоптимальное решение, поскольку файл war, который мы хотим развернуть, должен просто иметь дополнительный файл свойств, который задает среду, в которой должен загружаться контекст приложения Spring, чтобы развертывание не зависело от некоторого набора env var на сервер.

Я попытался выяснить, как это сделать, и нашел:

ConfigurableEnvironment.setActiveProfiles()

, который я могу использовать для программной установки профиля, но тогда я все еще не знаю, где и когда выполнять этот код. Где-то, где загружается весенний контекст? Можно ли загрузить параметр, который я хочу передать методу, из файла свойств?

ОБНОВЛЕНИЕ: Я только что нашел в документах , что я мог бы реализовать для установки активного профиля?

Ответы [ 4 ]

51 голосов
/ 21 декабря 2011

In web.xml

<context-param>
    <param-name>spring.profiles.active</param-name>
    <param-value>profileName</param-value>
</context-param>

Использование WebApplicationInitializer

Этот подход используется, когда у вас нет файла web.xml в среде Servlet 3.0 и вы загружаете Springполностью из Java:

class SpringInitializer extends WebApplicationInitializer {

    void onStartup(ServletContext container) {
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        rootContext.getEnvironment().setActiveProfiles("profileName");
        rootContext.register(SpringConfiguration.class);
        container.addListener(new ContextLoaderListener(rootContext));
    }
}

Где класс SpringConfiguration помечен @Configuration.

40 голосов
/ 22 декабря 2011

Ответ от Thomasz действителен до тех пор, пока имя профиля может быть предоставлено статически в файле web.xml, или если используется новый тип конфигурации без XML, где можно программно загрузить профиль для установки из файла свойств.

Поскольку мы все еще используем версию XML, я исследовал ее дальше и нашел следующее хорошее решение, в котором вы реализуете свой собственный ApplicationContextInitializer, где вы просто добавляете новый PropertySource с файлом свойств в список источников для поиска конфигурации конкретной среды.настройки.в приведенном ниже примере можно установить свойство spring.profiles.active в файле env.properties.

public class P13nApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    private static Logger LOG = LoggerFactory.getLogger(P13nApplicationContextInitializer.class);

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        try {
            environment.getPropertySources().addFirst(new ResourcePropertySource("classpath:env.properties"));
            LOG.info("env.properties loaded");
        } catch (IOException e) {
            // it's ok if the file is not there. we will just log that info.
            LOG.info("didn't find env.properties in classpath so not loading it in the AppContextInitialized");
        }
    }

}

Затем вам нужно добавить этот инициализатор в качестве параметра к ContextLoaderListener пружины следующим образом для вашего web.xml:

<context-param>
    <param-name>contextInitializerClasses</param-name>
    <param-value>somepackage.P13nApplicationContextInitializer</param-value>
</context-param>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Вы также можете применить его к DispatcherServlet:

<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextInitializerClasses</param-name>
        <param-value>somepackage.P13nApplicationContextInitializer</param-value>
    </init-param>
</servlet>
6 голосов
/ 26 декабря 2012

Почему-то у меня работает только один способ

public class ActiveProfileConfiguration implements ServletContextListener {   
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.setProperty(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, "dev");
        System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "dev");
    }

....

 <listener>
     <listener-class>somepackahe.ActiveProfileConfiguration</listener-class>
 </listener>
 <listener>
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
 </listener>
0 голосов
/ 13 июня 2015

Вот вариант подхода P13nApplicationContextInitializer. Однако на этот раз мы получаем путь к свойствам env из JNDI. В моем случае я установил глобальную переменную среды JNDI как coacorrect / spring-profile = file: /tmp/env.properties

  1. В tomcat / tomee server.xml добавьте это: <Environment name="coacorrect/spring-profile" type="java.lang.String" value="/opt/WebSphere/props"/>
  2. Далее, в tomcat / tomee добавьте в WAR-файл META-INF / context.xml <ResourceLink global="coacorrect/spring-profile" name="coacorrect/spring-profile" type="java.lang.String"/>
  3. В любой контейнер добавьте соответствующий файл в web.xml

    public class SpringProfileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{
    
    public static final Logger log = LoggerFactory.getLogger(SpringProfileApplicationContextInitializer.class);
    private static final String profileJNDIName="coacorrect/spring-profile";
    private static final String failsafeProfile="remote-coac-dbserver";
    
    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {
    
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
    
        try {
            InitialContext ic = new InitialContext();
            Object r1 = ic.lookup(profileJNDIName);
            if (r1 == null) {
                // try the tomcat variant of JNDI lookups in case we are on tomcat/tomee
                r1 = ic.lookup("java:comp/env/"+profileJNDIName);
            }
            if (r1 == null) {
                log.error("Unable to locate JNDI environment variable {}", profileJNDIName);
                return;
            }
    
            String profilePath=(String)r1;
            log.debug("Found JNDI env variable {} = {}",r1);
            environment.getPropertySources().addFirst(new ResourcePropertySource(profilePath.trim()));
            log.debug("Loaded COAC dbprofile path. Profiles defined {} ", Arrays.asList(environment.getDefaultProfiles()));
    
        } catch (IOException e) {
            // it's ok if the file is not there. we will just log that info.
            log.warn("Could not load spring-profile, defaulting to {} spring profile",failsafeProfile);
            environment.setDefaultProfiles(failsafeProfile);
        } catch (NamingException ne) {
            log.error("Could not locate JNDI variable {}, defaulting to {} spring profile.",profileJNDIName,failsafeProfile);
            environment.setDefaultProfiles(failsafeProfile);
        }
    }
    

    }

...