304 votes

Comment peut-on injecter la valeur d'une propriété dans un Printemps de Haricot qui a été configuré à l'aide d'annotations?

J'ai un tas de beans Spring qui sont pris sur le chemin de classe via des annotations, par exemple

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {
    // Implementation omitted
}

Au Printemps de fichier XML, il y a un PropertyPlaceholderConfigurer définis:

<bean id="propertyConfigurer" 
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
    <property name="location" value="/WEB-INF/app.properties" />
</bean> 

Je veux injecter une des propriétés de l'app.properites dans le bean indiqué ci-dessus. Je ne peux pas tout simplement faire quelque chose comme

<bean class="com.example.PersonDaoImpl">
    <property name="maxResults" value="${results.max}"/>
</bean>

Parce que PersonDaoImpl n'est pas dans le Ressort de fichier XML (il est pris du chemin de classe via des annotations). J'en ai autant que les suivantes:

@Repository("personDao")
public class PersonDaoImpl extends AbstractDaoImpl implements PersonDao {

    @Resource(name = "propertyConfigurer")
    protected void setProperties(PropertyPlaceholderConfigurer ppc) {
    // Now how do I access results.max? 
    }
}

Mais il n'est pas clair pour moi comment je accéder à la propriété, je suis intéressé dans de ppc?

299voto

Willie Wheeler Points 8632

Vous pouvez le faire au Printemps 3 en utilisant les EL de soutien. Exemple:

@Value("#{systemProperties.databaseName}")
public void setDatabaseName(String dbName) { ... }

@Value("#{strategyBean.databaseKeyGenerator}")
public void setKeyGenerator(KeyGenerator kg) { ... }

systemProperties est un objet implicite et strategyBean est un haricot nom.

Un exemple, qui fonctionne lorsque vous voulez prendre une propriété à partir d'un Properties objet. Il montre aussi que vous pouvez appliquer @Value de domaines:

@Value("#{myProperties['github.oauth.clientId']}")
private String githubOauthClientId;

Voici un blog que j'ai écrit sur ce sujet pendant un peu plus d'infos.

149voto

barrymac Points 1146

Personnellement, j'adore cette nouvelle façon de Printemps 3.0 à partir de la documentation:

    private @Value("${propertyName}") String propertyField;

pas de getters ou setters!

avec les propriétés d'être chargé via la config:

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
      p:location="classpath:propertyFile.properties" name="propertiesBean"/>

Pour de plus amples mon allégresse, je peux même le contrôle de cliquer sur l'expression EL à l'ide, et il m'amène à la définition de propriété de!

Il y a aussi le totalement non xml version:

@PropertySource("classpath:propertyFile.properties")
public class AppConfig {

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        return new PropertySourcesPlaceholderConfigurer();
    }

31voto

shane lee Points 161

<context:property-placeholder ... /> est l'équivalent XML pour la PropertyPlaceholderConfigurer.

Exemple: applicationContext.xml

<context:property-placeholder location="classpath:test.properties"/>  

Classe de composant

 private @Value("${propertyName}") String propertyField;

15voto

Dónal Points 61837

Une autre alternative est d'ajouter la appProperties bean indiqué ci-dessous:

<bean id="propertyConfigurer"   
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="/WEB-INF/app.properties" />
</bean> 


<bean id="appProperties" 
          class="org.springframework.beans.factory.config.PropertiesFactoryBean">
        <property name="singleton" value="true"/>

        <property name="properties">
                <props>
                        <prop key="results.max">${results.max}</prop>
                </props>
        </property>
</bean>

Lorsqu'elles sont récupérées, ce haricot peut être converti en java.util.Properties qui contiendra une propriété nommée results.max dont la valeur est lue à partir d' app.properties. Encore une fois, ce haricot peut être la dépendance de l'injection (comme une instance de java.util.Les propriétés) dans l'une des classes via @annotation de Ressources.

Personnellement, je préfère cette solution (pour les autres j'ai proposé), comme vous pouvez limiter exactement les propriétés qui sont exposés par des appProperties, et n'ont pas besoin de lire app.les propriétés de deux fois.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X