如何配置Spring的环境变量
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何配置Spring的环境变量相关的知识,希望对你有一定的参考价值。
参考技术A Java1.8环境变量配置:a.JAVA_HOME:jdk安装目录
b.CLASSPATH:.;%JAVA_HOME%\lib”
c.PATH:%JAVA_HOME%\bin
配置环境变量方法:
1.点击计算机,右键弹出菜单,选择属性;
2.进入属性之后,选择高级系统设置;
3.点击环境变量,然后依次添加环境变量已经变量值即可。本回答被提问者采纳
如何通过属性文件而不是通过 env 变量或系统属性设置活动 spring 3.1 环境配置文件
【中文标题】如何通过属性文件而不是通过 env 变量或系统属性设置活动 spring 3.1 环境配置文件【英文标题】:How to set active spring 3.1 environment profile via a properites file and not via an env variable or system property 【发布时间】:2012-01-25 03:03:22 【问题描述】:我们使用 spring 3.1 的新环境配置文件功能。我们目前通过在部署应用程序的服务器上设置环境变量 spring.profiles.active=xxxxx 来设置活动配置文件。
我们认为这是一个次优的解决方案,因为我们要部署的 war 文件应该只有一个额外的属性文件,该文件设置 spring 应用程序上下文应该加载的环境,因此部署不依赖于设置的某些 env var服务器。
我试图弄清楚如何做到这一点并发现:
ConfigurableEnvironment.setActiveProfiles()
我可以使用它以编程方式设置配置文件,但我仍然不知道何时何地执行此代码。弹簧上下文加载的地方?我可以从属性文件加载我想传递给方法的参数吗?
更新:我刚刚在docs 找到了我可能能够实施它来设置活动配置文件?
【问题讨论】:
将活动配置文件作为服务器的属性通常是正确的方法。因为您可能有不同的数据源用于预生产、开发和生产服务器。如果服务器可以提供活动配置文件,您可以将相同的代码部署到多个环境而无需更改。这当然可能不适合您的用例,但值得指出。 您希望将环境编码到 WAR 文件中?这不是违背初衷吗?您应该有一个适用于所有环境的 war 文件。设置每个服务器的活动配置文件或使用系统属性或环境变量。 感谢 Alex 指出这一点,虽然这不是我们的选择,但我知道这一点,因为我们希望在部署时控制配置文件。 另外@ericacm:我们确实希望提供配置文件以在我们自己的部署时设置,以不依赖于我们无法控制的服务器上设置的环境。我认为应该只进行一场战争而不将环境编码到其中是正确的。在我下面的回答中,您会看到我们如何通过加载 env.properties 来实现这一点。 @ShadowWizard Woh!!,这不是故意的,这是一个错误,我编辑了很多,有时会出错 【参考方案1】:在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
注释。
【讨论】:
非常感谢您的回答。我确实喜欢使用 xml less WebApplicationInitializer 的解决方案,但我们确实使用 XML。 -Dspring.profiles.active=someprofile 我认为更易于管理。因为它在某些情况下不必打开,将应用默认值。 您可能想改用spring.profiles.default
。这样,可以使用系统属性 -Dspring.profiles.active
覆盖活动配置文件
Java 配置:如果您使用 AbstractAnnotationConfigDispatcherServletInitializer,您可以覆盖 createServletApplicationContext 并另外配置上下文。 Example【参考方案2】:
Thomasz 的回答是有效的,只要配置文件名称可以在 web.xml 中静态提供,或者使用新的无 XML 配置类型,可以通过编程方式加载配置文件以从属性文件中设置。
由于我们仍然使用 XML 版本,我进一步调查并发现了以下不错的解决方案,您可以在其中实现自己的 ApplicationContextInitializer
,您只需将带有属性文件的新 PropertySource 添加到源列表中以搜索特定于环境的配置设置.在下面的示例中,可以在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");
然后您需要将该初始化程序作为参数添加到 spring 的 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>
【讨论】:
我只是好奇@F*** 为什么你称它为 P13n。不久前,我为一家公司编写了一些个性化代码,我使用了 P13N 一词,它是用 Java 编写的,并使用了 Spring。这可能只是一个巧合,但只是好奇。 如何在 web.xml 之外添加初始化器,例如在 myapplication.xml 上下文中? 是否可以使用DispatcherServlet
而不使用ContextLoaderListener
?
我无法使用 @Value($propName) 将配置注入 bean,但我能够使用 @Value(#environment[propName]) 注入配置。为什么会这样?【参考方案3】:
由于某种原因,只有一种方法适合我
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>
【讨论】:
完美。正是我需要的。谢谢 我使用的是 AbstractAnnotationConfigDispatcherServletInitializer 而不是 ApplicationContextInitializer 或 WebApplicationInitializer。该解决方案适用于这种情况,不需要 xml。【参考方案4】:这是 P13nApplicationContextInitializer 方法的一种变体。但是,这一次我们从 JNDI 获取 env 属性的路径。就我而言,我将 JNDI 全局环境变量设置为 coacorrect/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);
【讨论】:
以上是关于如何配置Spring的环境变量的主要内容,如果未能解决你的问题,请参考以下文章
如何通过属性文件而不是通过 env 变量或系统属性设置活动 spring 3.1 环境配置文件
使用环境变量在 Spring Boot 中配置 MongoDB