在SpringBoot中加载配置文件中的配置主要有三种方式:
为了介绍方便,首先来创建一个配置文件,如下所示:
server.port=8888
user.username=zhangsan
user.sex=man
user.age=30
system.enable=true
使用@Value注解来引入配置文件中的值时,可以有两种方式来引入:
一、创建一个配置的类
二、在使用的时候直接引入(这里不做介绍)
@Data
@Configuration
public class ValueConfig {
@Value("${user.username}")
private String userName;
@Value("${user.sex}")
private String sex;
@Value("${user.age}")
private Integer age;
}
使用的时候直接引入配置就好:
@Autowired
private ValueConfig valueConfig;
@RequestMapping(value="/value",method=RequestMethod.GET)
public String valueConfigTest() {
String value=valueConfig.getUserName()+" "+valueConfig.getSex()+" "+valueConfig.getAge();
System.out.println(value);
return value;
}
引入配置文件的值时,只要直接将Environment类引入即可,使用如下:
@Autowired
private Environment environment;
@RequestMapping(value="/environment",method=RequestMethod.GET)
public String environmentTest() {
String value=environment.getRequiredProperty("user.username")+" "
+environment.getRequiredProperty("user.sex")+" "+environment.getRequiredProperty("user.age");
System.out.println(value);
return value;
}
使用@ConfigurationProperties注解来进行配置文件的注入时,需要定义一个配置类,如下所示:
@Data
@Configuration
@ConfigurationProperties(prefix="user")
public class PropertiesConfig {
private String userName;
private String sex;
private Integer age;
}
// prefix---指定配置项中的前缀
使用时,直接引入PropertiesConfig 就好:
@Autowired
private PropertiesConfig proConfig;
@RequestMapping(value="/proConfig",method=RequestMethod.GET)
public String proConfigTest() {
String value=proConfig.getUserName()+" "+proConfig.getSex()+" "+proConfig.getAge();
System.out.println(value);
return value;
}
注意:
1、使用@ConfigurationProperties的配置类中@Configuration注解不能少,因为@ConfigurationProperties在项目加载的时候并不能够将配置类作为bean添加到Spring的容器中。
2、如果不想在配置类中使用@Configuration注解,也可以用其他的形式,如在项目的启动类中添加@EnableConfigurationProperties(value= {PropertiesConfig.class})一样可以达到bean注入的效果。
@ConditionalOnProperty注解可以用来控制某一个配置是否生效,这里可以先创建一个配置类:
@Configuration
public class CondConfig {
@Autowired
private ValueConfig valueConfig;// 引用了上边介绍的类
@Bean
@ConditionalOnProperty(name="system.enable",havingValue="true",matchIfMissing=true)
public String printUserStr() {
String value=valueConfig.getUserName()+" "+valueConfig.getSex()+" "+valueConfig.getAge();
return value;
}
}
@ConditionalOnProperty中的参数介绍:
1、name—配置文件(application.properties)中,配置的属性名
2、havingValue 配置读取的属性值跟havingValue做比较,如果一样则返回true;否则返回false;如果返回值为false,则该configuration不生效;为true则生效。
3、matchIfMissing = true表示如果没有在application.properties配置该属性,则默认为条件符合。
@Configuration使用在类上,作用相当于Spring中的xml文件
@Bean注解作用在方法上,声明当前方法的返回值是一个bean
例如上面的CondConfig类中,printUserStr()方法上引用了@Bean注解,所以就可以直接使用:
@Autowired
private String printUserStr;// printUserStr()的返回值就是一个Bean,Bean名称默认使用首字母为小写的方法名,例如printUserStr()生成Bean的名称为printUserStr;PrintUserStr()生成Bean的名称也为printUserStr。
@RequestMapping(value="/condConfig",method=RequestMethod.GET)
public String condConfigTest() {
return printUserStr;
}
注意:当时用@Autowired注入Bean的时候,@Autowired先根据类型(如上述中的String)来进行查找,如果没有找到会报错,如果找到多个同类型的,则会继续根据设置的参数名称(如上述中的printUserStr)来进行Bean名称的匹配,如果匹配成功则可以正常执行,如果不能(例如将private String printUserStr;改为private String printUser;)则会抛出如下的错误:
Field printUser in com.learn.controller.TestController required a single bean, but 2 were found:
- printUserStr: defined by method 'printUserStr' in class path resource [com/learn/config/CondConfig.class]
- printUserStr1: defined by method 'printUserStr1' in class path resource [com/learn/config/CondConfig.class]
出现这个问题的原因是因为,有两个String类型的Bean,无法判断注入哪一个。
如果没有在方法上添加@Bean注解,则需要使用如下的方式:
@Autowired
private CondConfig condConfig;
@RequestMapping(value="/condConfig",method=RequestMethod.GET)
public String condConfigTest() {
String value=condConfig.printUserStr();
return value;
}
参考博客:SpringBoot - @Configuration、@Bean注解的使用详解(配置类的实现)
Import注解,可以将普通的类或者@Configuration标注的类引入到Sring的容器中,使用方式如下:
@Configuration
@Import(value= {ValueConfig.class})
public class ImportConfig {
}
如上所示在上边的ImportConfig中引入了ValueConfig类(前边已经介绍过),这时ValueConfig类中是否使用@Configuration注解,都会将ValueConfig注入到容器中,然后就可以正常的使用。