获取property文件中的值Value使用和ConfigurationProperties以及PropertySource使用

Spring (Boot)获取参数的方式有很多,其中最被我们熟知的为@Value了,它不可谓不强大。

今天就针对我们平时最长使用的@Value,以及可能很少人使用的@PropertySource、@ConfigurationProperties等相关注解进行一个详细
spring boot 使用@ConfigurationProperties
有时候有这样子的情景,我们想把配置文件的信息,读取并自动封装成实体类,这样子,我们在代码里面使用就轻松方便多了,这时候,我们就可以使用@ConfigurationProperties,它可以把同类的配置信息自动封装成实体类

首先在配置文件里面,这些信息是这样子滴

connection.username=admin
connection.password=kyjufskifas2jsfs
connection.remoteAddress=192.168.1.1
这时候我们可以定义一个实体类在装载配置文件信息


@Component
@Date
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {

    private String username;
    private String remoteAddress;
    private String password ;


}
我们还可以把@ConfigurationProperties还可以直接定义在@bean的注解上,这是bean实体类就不用@Component和@ConfigurationProperties了

@SpringBootApplication
public class DemoApplication{

    //...

    @Bean
    @ConfigurationProperties(prefix = "connection")
    public ConnectionSettings connectionSettings(){
        return new ConnectionSettings();

    }

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
然后我们需要使用的时候就直接这样子注入

@RestController
@RequestMapping("/task")
public class TaskController {

@Autowired ConnectionSettings conn;

@RequestMapping(value = {"/",""})
public String hellTask(){
    String userName = conn.getUsername();     
    return "hello task !!";
}

}

如果发现@ConfigurationPropertie不生效,有可能是项目的目录结构问题,

你可以通过@EnableConfigurationProperties(ConnectionSettings.class)来明确指定需要用哪个实体类来装载配置信息

@Configuration
@EnableConfigurationProperties(ConnectionSettings.class)
 public class MailConfiguration { 
    @Autowired private MailProperties mailProperties; 

    @Bean public JavaMailSender javaMailSender() {
      // omitted for readability
    }
 }

 
 @PropertySouce是spring3.1开始引入的基于java config的注解

通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。例如:

@Configuration
@PropertySource("classpath:config/clearLshjTask.properties")
public class PropertiesConfig {
 
    @Value("${jobs.schedule}")
    private String corn;
    
    
    
    
    public String getCorn() {
        return corn;
    }
 
 
 
 
    //要想使用@Value 用${}占位符注入属性,这个bean是必须的,这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key')  
    @Bean
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
       return new PropertySourcesPlaceholderConfigurer();
    }
@ConfigurationProperties 是将application配置文件的某类名下所有的属性值,自动封装到实体类中。
@Value 是将application配置文件中,所需要的某个属性值,封装到java代码中以供使用。
@Value
@Value注解的注入非常强大,可以借助配置文件的注入、也可以直接注入

直接注入属性
注入普通字符串
    @Value("normal")
    private String normal; // normal (显然这种注入的意义不大)
注入操作系统属性
@Value("#{systemProperties['os.name']}")
    private String systemPropertiesName; 
//效果等同于  是因为spring模版把系统变量否放进了Enviroment
@Value("${os.name}")
    private String systemPropertiesName; 
注入表达式结果
@Value("#{ T(java.lang.Math).random() * 100.0 }")
    private double randomNumber; //41.29185128620939
注入其它Bean的属性:Person类的name属性
    @Bean
    public Person person() {
        Person person = new Person();
        person.setName("fangshixiang");
        return person;
    }

//注入属性
    @Value("#{person.name}")
    private String personName;

    @Test
    public void contextLoads() {
        System.out.println(personName); //fangshixiang
    }
注入文件资源
 在resources下放置一个jdbc.properties配置文件。然后可以直接注入
    @Value("classpath:jdbc.properties")
    private Resource resourceFile; // 注入文件资源

    @Test
    public void contextLoads() throws IOException {
        System.out.println(resourceFile); //class path resource [jdbc.properties]
        String s = FileUtils.readFileToString(resourceFile.getFile(), StandardCharsets.UTF_8);
        System.out.println(s);
        //输出:
        //db.username=fangshixiang
        //db.password=fang
        //db.url=jdbc:mysql://localhost:3306/mytest
        //db.driver-class-name=com.mysql.jdbc.Driver
    }
注入Url资源
    @Value("http://www.baidu.com")
    private Resource testUrl; // 注入URL资源


    @Test
    public void contextLoads() {
        System.out.println(testUrl); //URL [http://www.baidu.com]
    }
    @Value中$和#的区别
语法:
 ${ properties }和#{ SpEL }的语法区别

${ property : default_value }
#{ obj.property? : default_value }  表示SpEl表达式通常用来获取bean的属性,或者调用bean的某个方法。当然还有可以表示常量
正常使用的情况,这里不做过多的介绍了,现在介绍一些异常情况

${ properties }`:这种比较简单,如果key找不到,启动会失败。如果找不到的时候也希望正常启动,可以采用冒号+默认值的方式
#{ obj.property? : default_value }

    @Value("#{person}")
    private Person value;

    @Test
    public void contextLoads() {
        System.out.println(value); //Person(name=fangshixiang, age=null, addr=null, hobby=null)
    }
     @Value("#{person.name}")
    private String personName;

    @Value("#{person.age}")
    private String perAge;

    //注入默认值
    @Value("#{person.age?:20}")
    private String perAgeDefault;
    获取级联属性,下面两种方法都是ok的:

    @Value("#{person.parent.name}")
    private String parentName1;

    @Value("#{person['parent.name']}")
    private String parentName2;

    @Test
    public void contextLoads() {
        System.out.println(parentName1); //fangshixiang
        System.out.println(parentName2); //fangshixiang
    }
    @PropertySource:加载配置属性源
此注解也是非常非常的强大,用好了,可以很好的实现配置文件的分离关注,大大提高开发的效率,实现集中化管理

最简单的应用,结合@Value注入属性值(也是最常见的应用)
通过@PropertySource把配置文件加载进来,然后使用@Value获取

@Configuration
@PropertySource("classpath:jdbc.properties")
public class PropertySourceConfig {

    @Value("${db.url}")
    private String dbUrl;

    @PostConstruct
    public void postConstruct() {
        System.out.println(dbUrl); //jdbc:mysql://localhost:3306/mytest
    }
}
@PropertySource各属性介绍
value:数组。指定配置文件的位置。支持classpath:和file:等前缀
 Spring发现是classpath开头的,因此最终使用的是Resource的子类ClassPathResource。如果是file开头的,则最终使用的类是FileSystemResource
ignoreResourceNotFound:默认值false。表示如果没有找到文件就报错,若改为true就不报错。建议保留false
encoding:加载进来的编码。一般不用设置,可以设置为UTF-8等等
factory:默认的值为DefaultPropertySourceFactory.class。

猜你喜欢

转载自blog.csdn.net/zpflwy1314/article/details/102843048