简体   繁体   English

如何在Spring applicationContext.xml中读取JVM参数

[英]How do I read JVM arguments in the Spring applicationContext.xml

I have a JSF web application with Spring and I am trying to figure out a way to reference the JVM arguments from the applicationContext.xml. 我有一个使用Spring的JSF Web应用程序,我试图找到一种方法来引用applicationContext.xml中的JVM参数。 I am starting the JVM with an environment argument (-Denv=development, for example). 我使用环境参数启动JVM(例如-Denv = development)。 I have found and tried a few different approaches including: 我找到并尝试了一些不同的方法,包括:

<bean id="myBean" class="com.foo.bar.myClass">
  <property name="environment">
    <value>${environment}</value>
  </property>
</bean>

But, when the setter method is invoked in MyClass, the string "${environment}" is passed, instead of "development". 但是,当在MyClass中调用setter方法时,将传递字符串“$ {environment}”,而不是“development”。 I have a work around in place to use System.getProperty(), but it would be nicer, and cleaner, to be able to set these values via Spring. 我有一个使用System.getProperty()的工作,但是能够通过Spring设置这些值会更好,更清晰。 Is there any way to do this? 有没有办法做到这一点?

Edit: What I should have mentioned before is that I am loading properties from my database using a JDBC connection. 编辑:之前我应该​​提到的是我使用JDBC连接从我的数据库加载属性。 This seems to add complexity, because when I add a property placeholder to my configuration, the properties loaded from the database are overridden by the property placeholder. 这似乎增加了复杂性,因为当我向配置添加属性占位符时,属性占位符将覆盖从数据库加载的属性。 I'm not sure if it's order-dependent or something. 我不确定它是依赖于顺序还是其他东西。 It's like I can do one or the other, but not both. 这就像我可以做其中一个,但不是两个。

Edit: I'm currently loading the properties using the following configuration: 编辑:我目前正在使用以下配置加载属性:

<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc.mydb.myschema"/> 
</bean>

<bean id="props" class="com.foo.bar.JdbcPropertiesFactoryBean">
    <property name="jdbcTemplate">
        <bean class="org.springframework.jdbc.core.JdbcTemplate">
            <constructor-arg ref="myDataSource" />
        </bean>
    </property>
</bean>

<context:property-placeholder properties-ref="props" />

You can use Spring EL expressions, then it is #{systemProperties.test} for -Dtest="hallo welt" 你可以使用Spring EL表达式,然后它是#{systemProperties.test} -Dtest="hallo welt" #{systemProperties.test} for -Dtest="hallo welt"

In your case it should be: 在你的情况下,它应该是:

<bean id="myBean" class="com.foo.bar.myClass">
  <property name="environment">
    <value>#{systemProperties.environment}</value>
  </property>
</bean>

The # instead of $ is no mistake! #而不是$是没错的!

$ would refer to place holders, while # refers to beans, and systemProperties is a bean. $表示占位符,而#表示bean,而systemProperties是bean。


May it is only a spelling error, but may it is the cause for your problem: In the example for your command line statement you name the variable env 可能只是拼写错误,但可能是您的问题的原因:在命令行语句的示例中,您将变量命名为env

( -Denv=development , for example... -Denv=development ,例如...

But in the spring configuration you name it environment . 但在spring配置中,您将其命名为environment But both must be equals of course! 但两者当然必须是平等的!

If you register a PropertyPlaceholderConfigurer it will use system properties as a fallback. 如果您注册PropertyPlaceholderConfigurer,它将使用系统属性作为后备。

For example, add 例如,添加

<context:property-placeholder/>

to your configuration. 到你的配置。 Then you can use ${environment} in either your XML configuration or in @Value annotations. 然后,您可以在XML配置或@Value注释中使用${environment}

You can load a property file based on system property env like this: 您可以根据系统属性env加载属性文件,如下所示:

   <bean id="applicationProperties"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="ignoreResourceNotFound" value="false" />
      <property name="ignoreUnresolvablePlaceholders" value="true" />
      <property name="searchSystemEnvironment" value="false" />
      <property name="locations">
         <list>
            <value>classpath:myapp-${env:prod}.properties</value>
         </list>
      </property>
   </bean>

If env is not set default it to production otherwise development and testing teams can have their flavor of app by setting -Denv=development or -Denv=testing accordingly. 如果未将env设置为默认生产,否则开发和测试团队可以通过设置-Denv=development-Denv=testing相应的测试来获得应用程序的风格。

Use #{systemProperties['env']} . 使用#{systemProperties['env']} Basically pass the propertyName used in the Java command line as -DpropertyName=value . 基本上将Java命令行中使用的propertyName作为-DpropertyName=value In this case it was -Denv=development so used env . 在这种情况下,它是-Denv=development这么用env

Interestingly, Spring has evolved to handled this need more gracefully with PropertySources: http://spring.io/blog/2011/02/15/spring-3-1-m1-unified-property-management/ 有趣的是,Spring已经发展到使用PropertySources更优雅地处理这种需求: http//spring.io/blog/2011/02/15/spring-3-1-m1-unified-property-management/

With a few configurations and perhaps a custom ApplicationInitializer if you are working on a Web app, you can have the property placeholder handle System, Environment, and custom properties. 如果您正在使用Web应用程序,那么使用一些配置和可能的自定义ApplicationInitializer,您可以使用属性占位符处理系统,环境和自定义属性。 Spring provides PropertySourcesPlaceholderConfigurer which is used when you have in your Spring config. Spring提供了PropertySourcesPlaceholderConfigurer,它在Spring配置中使用。 That one will look for properties in your properties files, then System, and then finally Environment. 那个会在你的属性文件中寻找属性,然后是System,然后是环境。

Spring 3.0.7 Spring 3.0.7

<context:property-placeholder location="classpath:${env:config-prd.properties}" />

And at runtime set: -Denv=config-dev.properties 并在运行时设置:-Denv = config-dev.properties

If not set "env" will use default "config-prd.properties". 如果没有设置“env”将使用默认的“config-prd.properties”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM