【springboot读取配置文件】@ConfigurationProperties、@PropertySource和@Value

概念:

  • @ConfigurationProperties : 是springboot的注解,用于把主配置文件中配置属性设置到对于的Bean属性上

  • @PropertySource :是spring的注解,用于加载指定的属性配置文件到Spring的Environment中,可以和 @Value、@ConfigurationProperties配合使用

  • @EnableConfigurationProperties : 用来开启ConfigurationProperties注解配置;如果不使用的话,@ConfigurationProperties加入注解的类上加@Component也是可以交于springboot管理。

1、读取默认配置文件(application.properties、application.yml)

application.yml配置:

实现方式一 @ConfigurationProperties + @Component作用于类上

@ConfigurationProperties(prefix="person")
@Componment
@Data     // lombok,用于自动生成getter、setter
public class Person {
    private String name;
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

实现方式二 @ConfigurationProperties + @Bean作用在配置类的bean方法上

@Data
public class Person {
    private String name;
}

@Configuration
public class PersonConf{
    @Bean
    @ConfigurationProperties(prefix="person")
    public Person person(){
        return new Person();
    }  
} 

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;
    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

实现方式三 @ConfigurationProperties注解到普通类、 @EnableConfigurationProperties注解定义为bean

@ConfigurationProperties(prefix="person")
@Data
public class Person {
    private String name;
}
// 说明: @EnableConfigurationProperties可以直接注到启动类上,也可以放在自定义配置类,自定义配置类使用@Configuration标注
@SpringBootApplication
@EnableConfigurationProperties(Person.class)
public class DbApplication {
    public static void main(String[] args) {
        SpringApplication.run(DbApplication.class, args);
    }
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

实现方式四 @Value作用属性上

@RestController
@RequestMapping("/db")
public class TestController {
    @Value("${person.name}")
    private String name;

    @GetMapping("/person")
    public String parsePerson() {
        return name;
    }
}

实现方式五 使用自带的Environment对象

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Environment environment;

    @GetMapping("/person")
    public String parsePerson() {
        return environment.getProperty("person.name");
    }
}

2、读取自定义配置文件(比如:dangxiaodang.properties)

dangxiaodang.properties配置:(说明: PropertySource不支持yml、yaml,详细请看扩展内容)

实现方式一 @Configuration + @PropertySource + Environment

@Data
public class Person {
    private String name;
}

@Configuration
@PropertySource(value = "classpath:dangxiaodang.properties")
public class PersonConf {
    @Autowired
    private Environment environment;
    @Bean
    public Person person(){
        Person person = new Person();
        person.setName(environment.getProperty("person.name"));
        return person;
    }
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

实现方式二 @Configuration + @PropertySource + @Value

@Component
@PropertySource(value = "classpath:dangxiaodang.properties")
@Data
public class Person {
    @Value("${person.name}")
    private String name;
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

实现方式三 @Configuration + @PropertySource + @ConfigurationProperties

@Component
@PropertySource("classpath:dangxiaodang.properties")
@ConfigurationProperties(prefix = "person")
public class Person{
  private String name;
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}

扩展内容

  • 分析:@PropertySource 的注解中,有一个factory属性,可指定一个自定义的PropertySourceFactory接口实现,用于解析指定的文件。其中默认的实现是DefaultPropertySourceFactory,继续跟进,使用了PropertiesLoaderUtils.loadProperties进行文件解析,所以默认就是使用Properties进行解析的。
  • 解决方案:
    • 自定义实现类实现PropertySourceFactory
    • 自定义类继承DefaultPropertySourceFactory
  • 实现代码:
    dangxiaodang.yaml配置文件:(yml也支持)
public class YamlPropertySourceFactory implements PropertySourceFactory {
    @Override
    public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException {
        YamlPropertiesFactoryBean factory = new YamlPropertiesFactoryBean();
        factory.setResources(resource.getResource());
        factory.afterPropertiesSet();
        Properties ymlProperties = factory.getObject();
        String propertyName = name != null ? name : resource.getResource().getFilename();
        return new PropertiesPropertySource(propertyName, ymlProperties);
    }
}

@Component
@PropertySource(value = "classpath:dangbo.yml", factory = YamlPropertySourceFactory.class)   // 指定对应的factory
@ConfigurationProperties(prefix = "person")
@Data
public class Person {
    private String name;
}

@RestController
@RequestMapping("/db")
public class TestController {
    @Autowired
    private Person person;

    @GetMapping("/person")
    public String parsePerson() {
        return person.getName();
    }
}