【springboot讀取配置檔案】@ConfigurationProperties、@PropertySource和@Value

愛吃柚子的小頭發表於2021-02-22

概念:

  • @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();
    }
}

相關文章