49

我们使用 spring 3.1 的新环境配置文件功能。我们目前通过在部署应用程序的服务器上设置环境变量 spring.profiles.active=xxxxx 来设置活动配置文件。

我们认为这是一个次优的解决方案,因为我们要部署的 war 文件应该只有一个额外的属性文件,该文件设置 spring 应用程序上下文应该加载的环境,因此部署不依赖于服务器上设置的某些 env var。

我试图弄清楚如何做到这一点并发现:

ConfigurableEnvironment.setActiveProfiles()

我可以使用它以编程方式设置配置文件,但我仍然不知道在何时何地执行此代码。弹簧上下文加载的地方?我可以从属性文件加载我想传递给方法的参数吗?

更新:我刚刚在文档中找到了可以实施以设置活动配置文件的文档?

4

4 回答 4

51

web.xml

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

使用WebApplicationInitializer

当您在 Servlet 3.0 环境中没有web.xml文件并且完全从 Java 引导 Spring 时使用此方法:

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.

于 2011-12-21T09:40:02.997 回答
40

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");
        }
    }

}

然后,您需要将该初始化程序作为参数添加到ContextLoaderListenerspring 中,如下所示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>
于 2011-12-22T08:49:22.353 回答
6

出于某种原因,只有一种方法对我有用

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>
于 2012-12-26T09:49:59.650 回答
0

这是 P13nApplicationContextInitializer 方法的一种变体。但是,这一次我们从 JNDI 获取 env 属性的路径。就我而言,我将 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);
        }
    }
    

    }

于 2015-06-13T03:50:05.207 回答