@Value无需配置静态PropertySourcesPlaceholderConfigurer即可运行

时间:2017-04-08 19:36:18

标签: java spring

我试图在不使用@Autowiring和Spring Environment类时理解@PropertySource注释的行为。我试图在运行时使用@Value从属性文件中注入值。从我正在阅读的书和在线资源中,需要一个静态bean - PropertySourcesPlaceholderConfigurer,以便它可以工作。但对我来说,@ Value在没有PropertySourcesPlaceholderConfigurer静态bean的情况下也可以工作。有人能指出我正确的方向发生在这里的事情。可能是我遗漏了一些非常基本的东西。我们什么时候需要PropertySourcesPlaceholderConfigurer?什么时候不需要?

以下是我正在尝试的代码 -

package com.nilaysundarkar.demos;

public class Person {

    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

}

AppConfig.java -

package com.nilaysundarkar.demos;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource("classpath:/com/nilaysundarkar/demos/app.properties")
public class AppConfig {

    // This bean does not make any difference, or does it?
    /*@Bean
    public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer(){
        return new PropertySourcesPlaceholderConfigurer();
    }*/

    @Bean
    public Person person(@Value("${person.name}") String name){
        Person person = new Person();
        person.setName(name);
        return person;
    }

}

Bootstrap -

package com.nilaysundarkar.demos;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class App {

    public static void main(String[] args){

        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        Person person = context.getBean(Person.class);
        System.out.println(person.getName());
        ((AnnotationConfigApplicationContext)context).close();
    }

}

属性文件 - app.properties -

person.name=John Doe

pom -

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.nilaysundarkar.demos</groupId>
<artifactId>demos-runtime-injections</artifactId>
<version>0.0.1-SNAPSHOT</version>

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-beans</artifactId>
        <version>4.3.7.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>4.0.5.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.11</version>
    </dependency>
</dependencies>

当我运行App.java时 -

enter image description here

2 个答案:

答案 0 :(得分:4)

在春季靴子和弹簧中,application.properties(以及application.yml自弹簧靴开始)可以放在src/main/resources中,并由弹簧环境自动拾取。这意味着此文件中的所有属性都将加载到您的Environment,并且可以使用@Value进行注入。

您可以使用PropertySourcesPlaceholderConfigurer来注册更多属性来源,例如foo.properties[NAME].properties等,以便春天Environment添加它们。

当您使用@PropertySource时,您将另一个属性文件注册到您的弹簧Environment,因此您无需再使用自定义PropertySourcesPlaceholderConfigurer进行注册。 @PropertySource可以更轻松地注册不需要像文件系统中的文件那样的特殊加载的属性文件等。

只要您使用默认位置(application.properties),就无需注册此类型的自定义bean

修改

PropertySourcesPlaceholderConfigurer具有相同功能的@PropertySource示例。该示例基于驻留在foo.properties中的src/main/resources文件:

@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
    PropertySourcesPlaceholderConfigurer configurer = new PropertySourcesPlaceholderConfigurer();
    configurer.setLocation(new ClassPathResource("foo.properties"));
    return configurer;
}

答案 1 :(得分:1)

几个月前(大概是2018年2月)参加了Privotal的 Spring Core 课程,并且学生讲义(版本5.0.a)明确告诉您静态{{1}必须声明} bean,以便在使用 Spring Core 时解析PropertySourcesPlaceholderConfigurer占位符。但是,当我测试此行为时,忽略了有问题的Bean的创建,它的工作原理就像是我创建了解析占位符的Bean一样。在那之后,我联系了我的课程老师,因为我认为我的代码有问题,但是他后来确认我的代码是“好的”。他开始联系Pivotal,我们得到了一个官方答复

  

通过@PropertySource 注册的属性文件是自动的   已将添加到“   org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClass,   SourceClass),同时处理@Configuration类。

因此,显然Pivotal承认有关此文档的文档很差,并已提交new JIRA

顺便说一句,这仅适用于 Spring Core 4.3 + ,因为Spring Boot会自动为您创建此bean。

编辑:

如果您正在参加认证考试,目前尚不清楚Pivotal何时进行更新,但是此特定问题在考试中出现的几率很小(如果确实出现,您可以提出上诉)