web-dev-qa-db-fra.com

Evaluation de l'annotation spring @value en tant que booléen primitif

J'ai une classe commentée printanière @configuration MappingsClientConfig avec un champ booléen comme:

 @Value("${mappings.enabled:true}")
    private boolean mappingsEnabled;

Cette classe est importée dans une autre classe printanière annotée comme suit:

@Configuration
@Import(MappingsClientConfig.class)
public class LookupManagerConfig {

lors de l'instanciation de la classe via le contexte Spring dans un cas de test, le conteneur ne peut pas analyser la chaîne dans le champ booléen mappingsEnabled et j'obtiens:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private boolean com.barcap.tcw.mappings.economic.client.config.EconomicMappingsClientConfig.economicMappingsEnabled; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert value of type 'Java.lang.String' to required type 'boolean'; nested exception is Java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:502)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.Java:84)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.Java:282)
    ... 138 more
Caused by: org.springframework.beans.TypeMismatchException: Failed to convert value of type 'Java.lang.String' to required type 'boolean'; nested exception is Java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.Java:61)
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.Java:43)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.Java:718)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.Java:703)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.Java:474)
    ... 140 more
Caused by: Java.lang.IllegalArgumentException: Invalid boolean value [${mappings.enabled:true}]
    at org.springframework.beans.propertyeditors.CustomBooleanEditor.setAsText(CustomBooleanEditor.Java:124)
    at org.springframework.beans.TypeConverterDelegate.doConvertTextValue(TypeConverterDelegate.Java:416)
    at org.springframework.beans.TypeConverterDelegate.doConvertValue(TypeConverterDelegate.Java:388)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.Java:157)
    at org.springframework.beans.TypeConverterDelegate.convertIfNecessary(TypeConverterDelegate.Java:93)
    at org.springframework.beans.SimpleTypeConverter.convertIfNecessary(SimpleTypeConverter.Java:49)
    ... 144 more

Des pistes quant à ce qui me manque?

14
212

On dirait que vous manquez le PropertyPlaceholderConfigurer. Vous devez l'enregistrer en tant que post-processeur d'usine de haricots. Théoriquement, cela pourrait se faire comme ceci:

public class PostProcessorConfig {

    @Bean
    public BeanFactoryPostProcessor getPP() {
       PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
       configurer.setLocations(new Resource[]{new ClassPathResource("/my.properties")});
       return configurer;
    }
}

Cependant, il semble y avoir un bug qui pose d'autres problèmes à partir d'une configuration basée sur Java. Voir le billet pour les solutions de contournement.

5
Stefan Podkowinski

C'est un ancien thread, mais si vous souhaitez toujours injecter des valeurs non-String en utilisant l'annotation @Value Spring, procédez comme suit:

@Value("#{new Boolean('${item.priceFactor}')}")
private Boolean itemFactorBoolean;

@Value("#{new Integer('${item.priceFactor}')}")
private Integer itemFactorInteger;

Fonctionne pour moi sur le démarrage du printemps 1.5.9 avec Java 8.

8
realPK

Voici comment cela a été résolu dans notre projet, les autres réponses n’ayant pas fonctionné pour nous. Nous utilisions le lot de printemps, aussi.

config emploi principal:

@Configuration
@EnableBatchProcessing
@PropertySource("classpath:application.properties")
public class MainJobConfiguration {
    @Autowired
    PipelineConfig config;

    @Bean
    public PipelineConfig pipelineConfig(){
        return new PipelineConfig();
    }

    // To resolve ${} in @Value
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
        return new PropertySourcesPlaceholderConfigurer();
    }

    // job stuff ...
}

chargeur de configuration de propriétés:

public class PipelineConfig {
    @Value("${option}")
    private boolean option;
}

Notez que le @Value figure dans PipelineConfig, mais que les propriétés réelles à partir desquelles l'option est chargée sont spécifiées dans la classe de travail.

2
jmmut

Vous n’avez même pas besoin d’un fichier de propriétés, par exemple:

 <bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" />

1
user3690998