如何通过一个合适的文件来设置活动的spring 3.1环境configuration文件,而不是通过envvariables或系统属性
我们使用Spring 3.1的新环境configuration文件function。 我们目前通过在部署应用程序的服务器上设置环境variablesspring.profiles.active = xxxxx来设置活动configuration文件。
我们认为这是一个不太理想的解决scheme,因为我们想要部署的war文件应该只有一个额外的属性文件,它设置了spring应用程序上下文应该加载的环境,因此部署不依赖于服务器上的一些env var集合。
我试图找出如何做到这一点,发现:
ConfigurableEnvironment.setActiveProfiles()
我可以使用它来以编程方式设置configuration文件,但我仍然不知道何时何地执行此代码。 某处弹簧环境加载? 我可以加载我想传递给属性文件的方法参数?
更新:我刚刚发现在我可能能够实现设置活动configuration文件的文档?
在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
注释。
只要configuration文件名称可以在web.xml中静态提供,或者使用新的无XMLconfigurationtypes(可以通过编程方式加载configuration文件以从属性文件进行设置),Thomasz的答案就是有效的。
由于我们仍然使用XML版本进一步调查,发现了以下很好的解决scheme,您可以在其中实现自己的ApplicationContextInitializer
,只需将具有属性文件的新PropertySource添加到源列表以search特定于环境的configuration设置即可。 在下面的例子中,可以在env.properties
文件中设置spring.profiles.active
属性。
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"); } } }
然后,您需要将该初始化程序作为参数添加到您的web.xml
的Spring的ContextLoaderListener
中,如下所示:
<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>
出于某种原因,只有一种方法适用于我
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>
这是P13nApplicationContextInitializer方法的变体。 但是,这次我们从JNDI获得了env属性的path。 在我的情况下,我设置了一个JNDI全局环境variablescoacorrect / spring-profile = file:/tmp/env.properties
- 在tomcat / tomee server.xml中添加:
<Environment name="coacorrect/spring-profile" type="java.lang.String" value="/opt/WebSphere/props"/>
- 进一步,在tomcat / tomee中,添加到WAR的META-INF / context.xml中
<ResourceLink global="coacorrect/spring-profile" name="coacorrect/spring-profile" type="java.lang.String"/>
-
在任何容器中,在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); } }
}