简体   繁体   中英

Spring and @Value annotation

I'm trying to build a console application with Spring framework.

I have a class annotated by @SpringBootApplication :

@SpringBootApplication
public class LoaderApplication {

    public static void main(String[] args) {
        SpringApplication.run(LoaderApplication.class, args);
    }
}

And class annotated by @Component

@Component
public class ElasticLoader implements CommandLineRunner {

    // Elastic properties
    @Value("${elasticTransportAddress:#{null}}")
    private String elasticTransportAddress;

    private static final Logger log = LoggerFactory.getLogger(ElasticLoader.class);

    @Override
    public void run(String... arg) throws Exception {
        if (!( elasticTransportAddress != null && elasticTransportAddress.isEmpty() )) {
            log.error("[elasticTransportAddress] is not defined in property file");
            return;
        }
        log.info("-> ElasticLoader.run");
    }
}

As you can see, at this class I'm trying inject property elasticTransportAddress value by @Value annotation, but after running my application I can see that property elasticTransportAddress stays unassigned.

What did I miss?

Let me to add some notes:

I want to use my application with different property files. For this case I've created xml-context-config.xml with such content:

    <beans profile="companies">
    <!-- allows for ${} replacement in the spring xml configuration from the
        application-default.properties, application-dev files on the classpath -->
    <context:property-placeholder
            location="classpath:companies.properties"
            ignore-unresolvable="true" />

    <!-- scans for annotated classes in the com.env.dev package -->
    <context:component-scan base-package="ru.alexeyzhulin" />
</beans>

and use configuration file companies.properties which I placed in

在此处输入图片说明

My run configuration with the described profile:

在此处输入图片说明

And this profile is enabled, as I could see in the application logs:

2017-01-15 00:10:39.697  INFO 10120 --- [           main] ru.alexeyzhulin.LoaderApplication        : The following profiles are active: companies

But when I define properties in application.properties and use default profile, the property elasticTransportAddress becomes assigned.

You have an error in the if condition. This:

if (!( elasticTransportAddress != null && elasticTransportAddress.isEmpty() ))

is equivalent to this:

if (elasticTransportAddress == null || !elasticTransportAddress.isEmpty())

Thus, you get the error log message + return in TWO cases:

  1. If the property is not defined OR
  2. If the property is defined and it's value is non-empty.

The fix is to rewrite the if condition, eg

if (elasticTransportAddress == null || elasticTransportAddress.isEmpty())

Update 1: You of course need to make sure this value is really defined in application properties.


Update 2: Your xml-context-config.xml file isn't used by Spring at all. The recommended way is to use annotation-based configuration with @SpringBootApplication . You can do this by deleting xml-context-config.xml completely and creating a class annotated with @Configuration . This configuration-class can include annotations which define property sources . Eg:

@Configuration
@Profile("companies")
@PropertySource("classpath:companies.properties")
public final class LoaderApplication {
}

Note that you don't need to explicitly enable @ComponentScan if you use @SpringBootApplication .

rename companies.properties to application-companies.properties. Link to documentation

As the other @Alex said, you have to tell Spring from where you want to retrieve those properties. What you are missing here is another configuration and in your case (Annotation based configuration) you have to add this class:

@Configuration
public class MyConfiguration {

    @Bean
    public PropertyPlaceholderConfigurer getCompanyConfigurer() throws IOException {

        PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
        configurer.setLocations(new ClassPathResource("classpath:companies.properties"));
        configurer.setIgnoreUnresolvablePlaceholders(true);

        return configurer;
    }

}

Update:

If you are using the XML based configuration you have to tell Spring Boot what is the XML configuration deleting your annotation @SpringBootApplication in LoaderApplication and adding the XML to SpringApplication in this way:

SpringApplication.run("classpath:application-configuration.x‌​ml", args);

Finally add this line to the xml:

<context:property-placeholder ignore-unresolvable="true" location="classpath:companies.properties"/>

And, that's it, hope it helped.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM