web-dev-qa-db-fra.com

Définir la propriété système avec le fichier de configuration Spring

Configuration :
Spring 2.5, Junit 4, Log4j
L'emplacement du fichier log4j est spécifié à partir d'une propriété système

${log.location}

Au moment de l'exécution, la propriété système définie avec -D Java. Tout va bien.

Problème/Ce dont j'ai besoin:
Au moment du test unitaire, la propriété système n'est pas définie et l'emplacement du fichier n'est pas résolu.
L'application utilise Spring, souhaite simplement configurer Spring pour définir la propriété système.

Plus d'informations:
L'exigence concerne uniquement la configuration. Impossible d'introduire un nouveau Java ou entrées dans l'EDI. Idéalement, l'une des implémentations de configuration des propriétés de Spring pourrait gérer cela - je n'ai tout simplement pas été en mesure de trouver la bonne combinaison.

Cette idée est proche, mais doit ajouter Java code:
Spring SystemPropertyInitializingBean

Une aide là-bas? Toutes les idées sont appréciées.

56
Steve

Vous pouvez y parvenir avec la combinaison de deux MethodInvokingFactoryBeans

Créez un bean interne qui accède à System.getProperties et un bean externe qui appelle putAll sur les propriétés acquises par le bean interne:

<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>

(Vous pouvez bien sûr utiliser un seul bean et cibler System.setProperties (), mais vous remplaceriez alors les propriétés existantes, ce qui n'est pas une bonne idée.

Bref, voici ma petite méthode de test:

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"));
}

Et voici la sortie:

my.key: myvalue
my.key2: myvalue2
my.key3: myvalue3
Java.io.tmpdir: C:\DOKUME~1\SEANFL~1\LOKALE~1\Temp\
55
Sean Patrick Floyd

Il y avait une demande dans les commentaires pour un exemple Spring 3 sur la façon de procéder.

<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>
92
Patrick

Spring Batch a une classe SystemPropertyInitializer qui peut être utilisée pour définir une propriété système de manière un peu plus concise, par ex. pour forcer la journalisation JBoss à utiliser slf4j (avec 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"

N'oubliez pas d'ajouter l'attribut "dépend de" pour forcer la propriété système à être définie en premier.

10
paulcm

Pour une approche plus concise, essayez:

<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'}}"/>
3
Paul Rooney