如何通过属性文件而不是通过环境变量或系统属性设置活动的 spring 3.1 环境配置文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8587489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 04:49:34  来源:igfitidea点击:

How to set active spring 3.1 environment profile via a properites file and not via an env variable or system property

springenvironmentprofiles

提问by Fabian

We use the new environment profiles feature of spring 3.1. We currently set the active profile by setting the environment variable spring.profiles.active=xxxxx on the server to which we deploy the application.

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

We think this is a suboptimal solution as the war file we want to deploy should just have an additional properties file which sets the environment in which the spring app context should load so the deployment is not dependent on some env var set on the server.

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

I tried to figure out how to do that and found:

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

ConfigurableEnvironment.setActiveProfiles()

ConfigurableEnvironment.setActiveProfiles()

which I can use to programmatically set the profile but then I still don't know where and when to execute this code. Somewhere where the spring context loads up? Can I load the parameter I want to pass to the method from a properties file?

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

UPDATE: I just found at docswhich I might be able to implement to set the active profile?

更新:我刚刚在文档中找到,我可以实现它来设置活动配置文件?

采纳答案by Fabian

The answer from Thomasz is valid as long as the profile name can be provided statically in the web.xml or one uses the new XML-less configuration type where one could programmatically load the profile to set from a properties file.

只要配置文件名称可以在 web.xml 中静态提供,或者使用新的无 XML 配置类型,其中可以以编程方式加载配置文件以从属性文件进行设置,Thomasz 的答案就是有效的。

As we still use the XML version I investigated further and found the following nice solution where you implement your own ApplicationContextInitializerwhere you just add a new PropertySource with a properties file to the list of sources to search for environment specific configuration settings. in the example below one could set the spring.profiles.activeproperty in the env.propertiesfile.

由于我们仍在使用 XML 版本,我进一步调查并发现了以下不错的解决方案,您可以ApplicationContextInitializer在其中实现自己的解决方案,您只需将带有属性文件的新 PropertySource 添加到源列表中,以搜索特定于环境的配置设置。在下面的示例中,可以spring.profiles.activeenv.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");
        }
    }

}

You then need to add that initializer as a parameter to the ContextLoaderListenerof spring as follows to your web.xml:

然后,您需要将该初始化程序作为参数添加到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>

You can also apply it to DispatcherServlet:

您还可以将其应用于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>

回答by Tomasz Nurkiewicz

In web.xml

web.xml

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

Using WebApplicationInitializer

使用 WebApplicationInitializer

This approach is used when you don't have a web.xmlfile in Servlet 3.0 environment and are bootstrapping the Spring completely from Java:

当您web.xml在 Servlet 3.0 环境中没有文件并且完全从 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));
    }
}

Where SpringConfigurationclass is annotated with @Configuration.

其中SpringConfigurationclass 用@Configuration.

回答by Michail Nikolaev

For some reason only one way works for me

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

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>

回答by Jim Doyle

Here is a variation on the P13nApplicationContextInitializer approach. However, this time we obtain the path to env properties from JNDI. In my case I set a JNDI global environment variable as coacorrect/spring-profile = file:/tmp/env.properties

这是 P13nApplicationContextInitializer 方法的变体。但是,这一次我们从 JNDI 获取到 env 属性的路径。就我而言,我将 JNDI 全局环境变量设置为 coacorrect/spring-profile = file:/tmp/env.properties

  1. In tomcat/tomee server.xml add this: <Environment name="coacorrect/spring-profile" type="java.lang.String" value="/opt/WebSphere/props"/>
  2. Further, in tomcat/tomee, add to the WAR's META-INF/context.xml <ResourceLink global="coacorrect/spring-profile" name="coacorrect/spring-profile" type="java.lang.String"/>
  3. In any container, add appropriate in 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);
        }
    }
    

    }

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

    }