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。