@Value not resolved when using @PropertySource annotation. How to configure PropertySourcesPlaceholderConfigurer?

前端 未结 11 1167
情深已故
情深已故 2020-11-28 23:11

I have following configuration class:

@Configuration
@PropertySource(name = \"props\", value = \"classpath:/app-config.properties\")
@ComponentScan(\"service         


        
相关标签:
11条回答
  • 2020-11-28 23:36

    I found the reason @value was not working for me is, @value requires PropertySourcesPlaceholderConfigurer instead of a PropertyPlaceholderConfigurer. I did the same changes and it worked for me, I am using spring 4.0.3 release. I configured this using below code in my configuration file.

    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
       return new PropertySourcesPlaceholderConfigurer();
    }
    
    0 讨论(0)
  • 2020-11-28 23:36

    Since Spring 4.3 RC2 using PropertySourcesPlaceholderConfigurer or <context:property-placeholder> is not needed anymore. We can use directly @PropertySource with @Value. See this Spring framework ticket

    I have created a test application with Spring 5.1.3.RELEASE. The application.properties contains two pairs:

    app.name=My application
    app.version=1.1
    

    The AppConfig loads the properties via @PropertySource.

    package com.zetcode.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.context.annotation.PropertySource;
    
    @Configuration
    @PropertySource(value = "application.properties", ignoreResourceNotFound = true)
    public class AppConfig {
    
    }
    

    The Application injects the properties via @Value and uses them.

    package com.zetcode;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    import org.springframework.context.annotation.ComponentScan;
    
    @ComponentScan(basePackages = "com.zetcode")
    public class Application {
    
        private static final Logger logger = LoggerFactory.getLogger(Application.class);
    
        @Value("${app.name}")
        private String appName;
    
        @Value("${app.version}")
        private String appVersion;
    
        public static void main(String[] args) {
    
            var ctx = new AnnotationConfigApplicationContext(Application.class);
            var app = ctx.getBean(Application.class);
    
            app.run();
    
            ctx.close();
        }
    
        public void run() {
    
            logger.info("Application name: {}", appName);
            logger.info("Application version: {}", appVersion);
        }
    }
    

    The output is:

    $ mvn -q exec:java
    22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application name: My application
    22:20:10.894 [com.zetcode.Application.main()] INFO  com.zetcode.Application - Application version: 1.1
    
    0 讨论(0)
  • 2020-11-28 23:39

    In my case, depends-on="bean1" was within property-placeholder was causing the issue. I removed that dependency and used @PostConstruct to achieve the same original functionality and was able to read the new values too.

    0 讨论(0)
  • 2020-11-28 23:42

    as @cwash said;

    @Configuration
    @PropertySource("classpath:/test-config.properties")
    public class TestConfig {
    
         @Value("${name}")
         public String name;
    
    
         //You need this
         @Bean
         public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
            return new PropertySourcesPlaceholderConfigurer();
         }
    
    }
    
    0 讨论(0)
  • 2020-11-28 23:45

    The thing is: as far as I get it, <util:propertes id="id" location="loc"/>, is just a shorthand for

    <bean id="id" class="org.springframework.beans.factory.config.PropertiesFactoryBean">
      <property name="location" value="loc"/>
    </bean>
    

    (see documentation of util:properties). Thus, when you use util:properties, a standalone bean is created.

    @PropertySource, on the other hand, as documentation says is an

    annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment'.

    (see @PropertySource doc). So it doesn't create any bean.

    Then "#{a['something']}" is a SpEL expression (see SpEL), that means "get something from bean 'a'". When util:properties is used, the bean exists and the expression is meaningful, but when @PropertySource is used, there is no actual bean and the expression is meaningless.

    You can workaround this either by using XML (which is the best way, I think) or by issuing a PropertiesFactoryBean by yourself, declaring it as a normal @Bean.

    0 讨论(0)
  • 2020-11-28 23:46

    This can also be configured in java this way

    @Bean
    public static PropertySourcesPlaceholderConfigurer properties() {
        PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
        configurer.setIgnoreUnresolvablePlaceholders(true);
        configurer.setIgnoreResourceNotFound(true);
        return configurer;
    }
    
    0 讨论(0)
提交回复
热议问题