在项目中,我们通常把一些固定的信息写在配置文件中,要用的时候直接从配置文件中读取,这样维护起来非常简单方便。例如,最常见的就是数据库连接的配置信息了。
在 springboot 中,有多种获取配置文件中值的方法。
首先,准备用来封装所取值的实体类,下面的测试中将把配置文件中的值读取出来封装到以下的实体类中输出查看。
Person.java
public class Person {
private String lastName;
private Integer age;
private Boolean child;
private Date birth;
private Map hobbies;
private List
Pet.java
public class Pet {
private String name;
private Integer age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Pet [name=" + name + ", age=" + age + "]";
}
}
配置文件 application.properties
person.lastName=xiao
person.age=25
person.birth=1993/09/19
person.child=false
person.hobbies.k1=comic
person.hobbies.k2=music
person.friends=张三,李四
person.pet.name=dog
person.pet.age=5
使用注解 @ConfigurationProperties 取值非常简单,只要在实体类上加上就可以了。同时,需要把这个实体类加入容器中。prefix 告诉容器此类的属性与配置文件中 person 开头的属性相映射
@Component
@ConfigurationProperties(prefix="person")
public class Person {
private String lastName;
private Integer age;
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootConfigTest {
@Autowired
Person person;
@Test
public void propertiesContextLoads() {
System.out.println(person);
}
}
控制台打印如下
2019-04-13 16:36:04.845 INFO 4064 --- [ main] com.xiao.SpringbootConfigTest : Started SpringbootConfigTest in 7.899 seconds (JVM running for 9.222)
Person [lastName=xiao, age=25, child=false, birth=Sun Sep 19 00:00:00 CST 1993, hobbies={k1=comic, k2=music}, friends=[å¼ ä¸‰, æŽå››], pet=Pet [name=dog, age=5]]
2019-04-13 16:36:05.701 INFO 4064 --- [ Thread-2] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor'
发现中文乱码,在 IDEA 中,可以在 setting >> File Encodings 下方把默认编码改成utf-8,同时把 Transparent native-to-ascii conversion 勾选中就能解决这个乱码问题。但是在 eclipse 中只找到了更改编码方式 Window > Preference > General > Content Types > Text > Java Properties File,没有找到Transparent native-to-ascii conversion类似的在运行的时候转换成 ascii 码的功能。未能解决,如果有朋友有解决方法,希望能留言指教
最终把 application.properties 文件改成 yml 文件则可显示正常
注解 @Value 也能从配置文件中获取属性的值,需一个属性一个属性绑定
@Component
//@ConfigurationProperties(prefix="person")
public class Person {
@Value("${person.lastName}")
private String lastName;
@Value("#{12*2}")
private Integer age;
private Boolean child;
@ConfigurationProperties 与 @Value 的区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个一个绑定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
注:
松散绑定:不管配置文件中是 lastName 还是 last-name,实体类中 @ConfigurationProperties 都能把它的值绑定到 lastName 属性中
SpEL:Spring EL表达式
复杂类型:Map List Object
以下代码为 JSR303 数据校验
@Component
@ConfigurationProperties(prefix="person")
@Validated
public class Person {
@Email
private String lastName;
application.properties / application.yml 是全局配置文件,如果配置信息都放这个文件,可能会很大。因此我们另外新建一个 person.properties 文件存放 person 有关的配置信息,这样, @ConfigurationProperties , @Value 就无法直接获取配置文件的信息进行封装,这时,就要使用 @PropertySource 来指定读取的配置文件,可以指定多个配置文件
@Component
@ConfigurationProperties(prefix="person")
@PropertySource(value= {"classpath:person.properties"})
public class Person {
private String lastName;
private Integer age;
注:只能读取 .properties 文件,无法读取 .yml 文件
例如:要加载一个定义了 bean 的 xml 文件,就可以在主配置类/启动类中加入注解 @ImportResource 来导入这个文件,使得其中的 bean 注入 spring 容器中。
@SpringBootApplication
@ImportResource(locations= {"classpath:beans.xml"})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootConfigTest {
@Autowired
Person person;
@Autowired
ApplicationContext ac;
@Test
public void helloServiceTest() {
boolean flag = ac.containsBean("helloService");
System.out.println(flag);
}
@Test
public void propertiesContextLoads() {
System.out.println(person);
}
}
现在 springboot 推荐使用全注解的方式添加组件
1)写一个配置类,加入 @Configuration 指明当前类是一个配置类
2)在方法上加入 @Bean ,将方法的返回值注入到容器中,组件在容器中的 id 默认是方法名
@Configuration
public class MyConfig {
@Bean
public HelloService helloService() {
return new HelloService();
}
}