我们使用spring 3.1的新环境配置文件功能。我们当前通过在部署应用程序的服务器上设置环境变量spring.profiles.active = xxxxx来设置活动配置文件。
我们认为这是一个次优的解决方案,因为我们要部署的war文件应该只有一个额外的属性文件,用于设置spring应用程序上下文应该加载的环境,因此部署不依赖于某些env var on服务器
我试图找出如何做到并发现:
ConfigurableEnvironment.setActiveProfiles()
我可以用来以编程方式设置配置文件,但后来我仍然不知道在何时何地执行此代码。弹簧环境加载的地方?我可以从属性文件加载我想传递给方法的参数吗?
更新:我刚刚在docs找到了我可以实现设置有效个人资料的内容?
答案 0 :(得分: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
进行注释。
答案 1 :(得分:40)
只要可以在web.xml中静态提供配置文件名称,或者使用新的无XML配置类型,Thomasz的答案就是有效的,其中可以通过编程方式加载要从属性文件设置的配置文件。
由于我们仍然使用我进一步调查的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
的{{1}},如下所示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>
答案 2 :(得分: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>
答案 3 :(得分:0)
以下是P13nApplicationContextInitializer方法的变体。但是,这次我们从JNDI获取env属性的路径。在我的例子中,我将JNDI全局环境变量设置为coacorrect / spring-profile = file:/tmp/env.properties
<Environment name="coacorrect/spring-profile" type="java.lang.String" value="/opt/WebSphere/props"/>
<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);
}
}
}