SpringBoot攻略三、配置文件说明

自动配置

SpringBoot启动的时候加载主配置类(@SpringBootApplication注解修饰), @SpringBootApplication开启了自动配置功能 @EnableAutoConfiguration。


@EnableAutoConfiguration作用:利用AutoConfigurationImportSelector给spring容器中导入一些组件。
@SpringBootConfiguration作用:表示类提供springboot应用功能,继@Configuration。


跟踪一下AutoConfigurationImportSelector中的selectImports方法:



扫描所有jar包类路径下 META-INF/spring.factories;
把扫描到的这些文件的内容包装成properties对象;
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们 添加在容器中;
即将类路径下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加 入到了容器中。


这里,我们分析一下HttpEncodingAutoConfiguration,其他类似:



@Configuration:
定义配置类。
@EnableConfigurationProperties(HttpEncodingProperties.class):
启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties的属性绑定起来;并把HttpEncodingProperties加入到ioc容器。
@ConditionalOnWebApplication:
判断当前应用是否是web应用,如果是,当前配置类 生效
@ConditionalOnClass(CharacterEncodingFilter.class):
判断当前项目有没有这个类, CharacterEncodingFilter:SpringMVC中解决乱码的过滤器。
@ConditionalOnProperty(prefix="spring.http.encoding",value="enabled", matchIfMissing=true):
//判断配置文件中是否存在某个配置spring.http.encoding.enabled;matchIfMissing表示,即使我们配置文件中不配置spring.http.encoding.enabled=true,也是默认生效的;
@Conditional注解(Spring注解版):
条件注解,通过判断类路径下有没有配置相应jar包来确定是否加载和自动配置这个类。

所有在配置文件中能配置的属性都是在xxxxProperties类中封装的,配置文件的配置项 就可以参照其对应的这个属性类,默认就是UTF-8编码。



小结:
1、SpringBoot启动会加载大量的自动配置类;
2、首先检查SpringBoot默认的自动配置类是否满足我们的需求;
3、具体查看这个自动配置类中配置了哪些组件;
4、给容器中的自动配置类添加组件的时候,会从properties类中获取某些属性。我们 就可以在配置文件中指定这些属性的值;
5、xxxxAutoConfigurartion:自动配置类,给容器中添加组件Bean;xxxxProperties:封 装配置文件中相关属性;

Spring Boot提供了对应用进行自动化配置。相比以前 XML 配置方式,很多显式方式申 明是不需要的。二者,大多数默认的配置足够实现开发功能,从而更快速开发。

application.properties添加debug=true,可以在控制台查看自动配置报告信息。

拓展:@Conditional派生注解了解
核心:@Conditional指定的条件成立,才给容器中添加组件,配置类里面的所有内容才 生效;即自动配置类必须在一定的条件下才能生效:
@ConditionalOnJava: 系统的java版本是否符合要求
@ConditionalOnBean: 容器中存在指定Bean;
@ConditionalOnMissingBean: 容器中不存在指定Bean;
@ConditionalOnExpression: 满足SpEL表达式指定
@ConditionalOnClass: 系统中有指定的类
@ConditionalOnMissingClass: 系统中没有指定的类
@ConditionalOnSingleCandidate: 容器中只有一个指定的Bean,或者这个Bean是首 选Bean
@ConditionalOnProperty: 系统中指定的属性是否有指定的值
@ConditionalOnResource: 类路径下是否存在指定资源文件
@ConditionalOnWebApplication: 当前是web环境
@ConditionalOnNotWebApplication: 当前不是web环境

自定义属性(添加新属性、覆盖自动配置默认的属性)

Spring Boot使用默认的全局的配置文件:application.properties 或 application.yml,配置文件名固定。

实例
1、建立PersonProperties

package com.javasgj.springboot.configuration;

import java.util.List;
import java.util.Map;

import javax.validation.constraints.Email;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

/**
 * @Validated:对注入的值进行一些简单的校验;
 *              @Email          校验邮箱地址
 *              @AssertFalse    校验false
 *              @AssertTrue     校验true
 *              @DecimalMax(value=,inclusive=) 小于等于value,inclusive=true,是小于等于
 *              @DecimalMin(value=,inclusive=) 与上类似
 *              @Max(value=)    小于等于value
 *              @Min(value=)    大于等于value
 *              @NotNull        检查Null
 *              @Past           检查日期
 *              @Pattern(regex=,flag=)  正则
 *              @Size(min=, max=)       字符串,集合,map限制大小
 *              这些注解位于javax.validation.constraints包下,校验不通过时抛出异常。
 * @Component:作为Bean注入到spring容器,或者使用@Configuration;
 * @ConfigurationProperties:将配置文件中以person前缀的属性值自动绑定到对应的字段中;
 */
@Validated
@Component
@ConfigurationProperties(prefix="person")
public class PersonProperties {
    
    private String id;
    private String name;
    private int age;
    private String sex;
    @Email
    private String email;
    private String desc;
    private String desc1;
    private Map<String, String> maps;
    private List<String> list;
    
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public String getDesc1() {
        return desc1;
    }
    public void setDesc1(String desc1) {
        this.desc1 = desc1;
    }
    public Map<String, String> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, String> maps) {
        this.maps = maps;
    }
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
}

@ConfigurationProperties作用:默认加载classpath:application.properties或application.yml,如果同时存在则加载application.properties,并且把文件中以person前缀的属性值自动绑定到对应的l字段中。

当然如果是自定义属性值,也可以使用@PropertySource指定属性文件。
但是要覆盖框架自动配置的属性,只能使用默认的全局配置文件。

2、src/main/resources下建立:application.properties

#properties、yml同时存在,取properties内容


#调试信息,控制台查看自动配置报告信息
#debug=true


#自定义属性
person.name=Jim
person.age=28
person.sex=0
person.email=111@qq.com
#${}占位符,可以引用配置文件其他属性值,如果没有可以配置一个默认值:${person.name:default}
person.desc=I'm ${person.name}
#\n特殊字符,换行
person.desc1=I'm ${person.name} \n welcome!
#map数据类型,对象类型同理:person.对象名.属性名
person.maps.privince=js
person.maps.city=nj
#array、list、set集合
person.list[0]=0
person.list[1]=1
#随机数,通过 RandomValuePropertySource工具类。可以生成随机字符串、随机 int 、随机 long、某范围的随机数
#person.id=${random.int}
#person.id=${random.long}
#person.id=${random.long[1,100]}
#person.id=${random.uuid}
person.id=${random.value}

或者使用application.yml

person: 
 name: jim1
 age: 28
 sex: 0
 desc1: I am jim \n welcome!
 list: [0,1,2]
person.maps: {privince: js, city: nj}

注意:
1、yml格式冒号后面都要一个空格,属性前面也只能添加一个空格,可以使用在线编 辑yml(http://www.bejson.com/validators/yaml_editor/),有校验格式功能。
2、单引号:转义特殊字符,特殊字符只是一个普通的字符串数据,等同于没有引号
name: ‘zhangsan \n lisi’ 输出:zhangsan \n lisi
3、双引号:不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思
name: "zhangsan \n lisi" 输出:zhangsan
lisi

3、应用启动类

package com.javasgj.springboot.configuration;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * spring boot应用启动类
 */
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        
        SpringApplication.run(Application.class, args);
    }
}

4、编写测试类
pom.xml引入依赖

<!-- spring boot test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

PersonPropertiesTest:

package com.javasgj.springboot.configuration;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes=Application.class)
public class PersonPropertiesTest {

    @Autowired
    PersonProperties personProperties;
    
    @Test
    public void testGetName() {
        
        /**
         * springboot默认以ISO-8859-1编码读取properties文件内容,所以会有中文乱码,我们可以做如下处理解决乱码,
         * 或者使用yml类型文件进行配置,没有中文乱码问题。
         */
        /*try {
            System.out.println(new String(personProperties.getName().getBytes("ISO-8859-1"), "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }*/
        
        System.out.println("结果:" + personProperties.getId());
        System.out.println("结果:" + personProperties.getName());
        System.out.println("结果:" + personProperties.getEmail());
        System.out.println("结果:" + personProperties.getDesc1());
        System.out.println("结果:" + personProperties.getMaps().keySet().toString());
        System.out.println("结果:" + personProperties.getList().size());
    }
}

@SpringBootTest指定应用启动类Application
赶紧运行结果看看吧!

扩展:
Spring Boot不单单从application.properties获取配置,我们可以在程序中设置多种 配置属性。按照以下列表的优先级从高到低排列:
1、命令行参数
2、java:comp/env 里的 JNDI 属性
3、JVM 系统属性
4、操作系统环境变量
5、RandomValuePropertySource 属性类生成的 random.* 属性
6、应用外部的application-{profile}.properties或application.yml(带spring.profile)文件
7、应用内部的application-{profile}.properties或application.yml(带spring.profile)文件
6、应用以外的 application.properties(或 yml)文件
7、应用内部的 application.properties(或 yml)文件
8、在应用 @Configuration 配置类中,用 @PropertySource 注解声明的属性文件
9、SpringApplication.setDefaultProperties 声明的默认属性

注意一些特殊属性如:user.name,如果你在配置文件配置了此属性,但是确获取不到 配置文件中的值,为什么呢?因为系统属性有user.name,优先级又高,会获取到机器 当前用户账号。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,548评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,497评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,990评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,618评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,618评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,246评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,819评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,725评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,268评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,356评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,488评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,181评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,862评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,331评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,445评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,897评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,500评论 2 359