2010-07-26 78 views
52

配置
Spring 2.5中,JUnit 4中,Log4j的
log4j的文件位置從系統屬性設置系統屬性Spring配置文件

${log.location} 

在運行時,系統屬性設置與規定 - D java選項。一切都很好。

問題/我需要什麼:
在單元測試時,系統屬性沒有設置,和文件位置沒有解決。
應用程序使用Spring,想簡單地將Spring配置爲設置的系統屬性。

更多信息:
要求僅用於配置。無法將新的Java代碼或條目引入到IDE中。理想情況下,Spring的屬性配置實現之一可以處理這一點 - 我只是無法找到正確的組合。

這種想法是接近,但需要添加Java代碼:
Spring SystemPropertyInitializingBean

任何幫助在那裏?任何想法都表示讚賞。

+0

相關問題與另外的答案:http://stackoverflow.com/questions/11306951/how-to-set-environment-variable-or-system-property -in-spring-tests/41305482 – anre 2016-12-23 17:51:35

回答

54

可以達到與兩MethodInvokingFactoryBeans

組合創建訪問System.getProperties和調用的putAll由內部bean獲取的屬性的外豆內部豆:

<bean 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property 
     name="targetObject"> 
     <!-- System.getProperties() --> 
     <bean 
      class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
      <property name="targetClass" value="java.lang.System" /> 
      <property name="targetMethod" value="getProperties" /> 
     </bean> 
    </property> 
    <property 
     name="targetMethod" 
     value="putAll" /> 
    <property 
     name="arguments"> 
     <!-- The new Properties --> 
     <util:properties> 
      <prop 
       key="my.key">myvalue</prop> 
      <prop 
       key="my.key2">myvalue2</prop> 
      <prop 
       key="my.key3">myvalue3</prop> 

     </util:properties> 
    </property> 
</bean> 

(你當然可以使用一個bean和目標System.setProperties(),但是你會替換現有的屬性,這不是一個好主意。

無論如何,這裏是我的小測試方法:

public static void main(final String[] args) { 

    new ClassPathXmlApplicationContext("classpath:beans.xml"); 

    System.out.println("my.key: "+System.getProperty("my.key")); 
    System.out.println("my.key2: "+System.getProperty("my.key2")); 
    System.out.println("my.key3: "+System.getProperty("my.key3")); 

    // to test that we're not overwriting existing properties 
    System.out.println("java.io.tmpdir: "+System.getProperty("java.io.tmpdir")); 
} 

而這裏的輸出:

my.key: myvalue 
my.key2: myvalue2 
my.key3: myvalue3 
java.io.tmpdir: C:\DOKUME~1\SEANFL~1\LOKALE~1\Temp\ 
+0

謝謝。這工作。剩餘問題:似乎log4j是在這些新系統屬性初始化之前加載的另一個bean中初始化的。現在我開始弄清楚如何強制一個命令來初始化bean。 – Steve 2010-07-27 18:52:15

+1

使用Spring的依賴屬性。非常感謝這個答案......它是純金...... – HDave 2010-11-20 05:32:52

+7

Spring 3通過消除對第二個MethodInvokingFactoryBean的需求來簡化此操作。您使用SpEL並且目標對象行變爲 Patrick 2011-01-11 00:00:10

88

有在如何做到這一點Spring的3例中評論的請求。

<bean id="systemPrereqs" 
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
    <property name="targetObject" value="#{@systemProperties}" /> 
    <property name="targetMethod" value="putAll" /> 
    <property name="arguments"> 
     <!-- The new Properties --> 
     <util:properties> 
      <prop key="java.security.auth.login.config">/super/secret/jaas.conf</prop> 
     </util:properties> 
    </property> 
</bean> 
+0

不錯,謝謝 – 2011-09-12 19:30:10

+1

非常好。謝謝。 – toolkit 2011-09-14 20:24:25

+0

+1優秀。當我想到需要編寫多少代碼才能做到這一點。有時候春天很神奇。 :-) – 2011-11-09 19:57:39

10

Spring Batch的具有SystemPropertyInitializer類可以用來簡明略多設置系統屬性,例如強制JBoss的日誌使用SLF4J(與Spring JPA):

<bean id="setupJBossLoggingProperty" 
    class="org.springframework.batch.support.SystemPropertyInitializer" 
    p:keyName="org.jboss.logging.provider" p:defaultValue="slf4j"/> 

<bean id="entityManagerFactory" 
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" 
    depends-on="setupJBossLoggingProperty" 

記得添加「取決於上」屬性來強制將首先設置的系統屬性。

+0

我無法得到這個工作到最後。 'SystemPropertyInitializer'使用'afterPropertiesSet()',在調用''之後顯然不會被調用。 – Stewart 2017-03-21 03:17:04

3

對於一個更簡潔的方法試試:

<beans ... xmlns:p="http://www.springframework.org/schema/p" ...  
    <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean" 
     p:targetObject="#{@systemProperties}" p:targetMethod="setProperty" 
     p:arguments="#{{'org.jboss.logging.provider','slf4j'}}"/>