The World Best ST.

SpringBoot学习(一)

字数统计: 2.3k阅读时长: 9 min
2019/04/13 Share

SpringBoot基础学习

好好打基础啦

配置学习

@Value与@ConfigurationProperties的区别

@ConfigurationProperties是默认从全局文件中获取值的, 可以搭配@PropertySource使用加载指定配置文件

@ConfigurationProperties的区别 @Value
功能 批量注入 单条注入
松散绑定 支持, 可以写成person.last-name、person.lastName、person.last_name、PERSON_LAST_NAME 不支持
SpEL 不支持 支持
JSR303语法(有效性校验) 支持(在类上加入@Valid注解, 在变量上加上单个校验注解) 不支持
复杂类型注入 支持 不支持

@Value只能注入简单类型, 无法注入map, list等复杂类型
@Value可以进行SpEL运算, 例如: #{11*3600}这样

※如果只需要使用某一个配置文件, 那么使用Value就可以了
※如果专门写了一个javaBean的类, 那么可以使用@ConfigurationProperties

※需要注入时, 自己必须是容器里的一个组件

@PropertySource和@ImportResource

@PropertySource
作用: 用于读取指定的配置文件
用法:

1
@PropertySource(value = {"classpath:person.properties"})

@ImportResource
作用: 导入Spring的配置文件, 让配置文件里面的内容生效
自己编写的配置文件(xml文件), 无法自动识别, 如果想让Spring的配置文件生效, 则使用@ImportResource标注在启动类上
用法:

1
@ImportResource(localtions = {"classpath:beans.xml"})

SpringBoot中推荐的添加组件方式: 使用全注解方式

创建一个配置类

1
2
3
4
5
6
7
8
9
//标明当前是个配置类
@Configuration
public class MyAppConfig {
//将方法的返回值添加到容器中; 容器中这个组件默认的id就是方法名, 相当于配置文件中的<bean>
@Bean
public HelloService helloService(){
return new HelloService();
}
}

随机数与占位符

随机数
用法:

1
${random.int}, ${random.uuid}等

占位符
用法:

1
2
3
person.name=st
person.dog.name=${person.name}_mike #此处${person.name}为占位符
person.docg.nickname=${person.hello:lala}_mike #此处未定义person.hello则会默认为lala

多环境配置

方法1
新建多环境配置文件
application-dev.properties
application-prod.properties
application-test.properties

在application.properties中配置(SpringBoot会默认加载该配置文件)

1
spring.profile.active=dev/prod/test

方法2
在yml文件中使用配置块

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
server:
port: 8081
spring:
profiles:
active: dev/prod/test
---
spring:
profiles: dev
server:
port: 8082

---
spring:
profiles: prod
server:
port: 8083

---
spring:
profiles: test
server:
port: 8084

方法3
运行时传入参数
命令行参数

1
--spring.profiles.active=dev/prod/test

虚拟机参数

1
-Dspring.profiles.active=dev/prod/test

配置文件加载的优先级

优先级高的会覆盖优先级低的
优先级从低到高:

  • 类路径根目录: classpath:/
  • 类路径config文件: classpath:/config/
  • 项目根目录: 平行于src文件夹
  • 项目config目录: 平行于src文件夹

在项目打包结束后, 通过命令行的形式使用: –spring.config.location=路径, 来改变默认的配置文件位置

外部配置文件的优先级

优先级从高到低:

  • 命令行参数
  • jar包外部application-{profile}.properties或application.yml(带有spring.profile)配置文件
  • jar包内部application-{profile}.properties或application.yml(带有spring.profile)配置文件
  • jar包外部application.properties或application.yml(不带有spring.profile)配置文件
  • jar包内部application.properties或application.yml(不带有spring.profile)配置文件

配置加载原理

  1. @SpringBootApplication
  2. @EnableAutoConfiguration
  3. AutoConfigurationImportSelector
  4. selectImports方法
  5. getAutoConfigurationEntry方法
  6. getCandidateConfigurations方法
  7. loadFactoryNames方法
  8. loadSpringFactories方法
  9. 扫描所有jar包类路径下 META-INF/spring.factories
  10. 把扫描到的这些文件的内容包装秤properties对象
  11. 从properties中获取到EnableAutoConfiguration.class类(类名)的值, 然后把他们添加在容器中

总结: 将类路径下 META-INF/spring.factories里面所有EnableAutoConfiguration的值加入到了容器中
使用: org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration
进行流程解析

1
2
3
4
5
6
7
8
9
10
@Configuration	//表示这是一个配置类
@EnableConfigurationProperties({HttpProperties.class}) //启动指定类的ConfigurationProperties功能, 将配置文件中的值和HttpProperties绑定起来
@ConditionalOnWebApplication(type = Type.SERVLET) //判断当前应用是否为Web应用, 如果为Web应用则配置类的配置生效
@ConditionalOnClass({CharacterEncodingFilter.class}) //判断当前项目是否有CharacterEncodingFilter类:SpringMVC中进行乱码解决的过滤器
@ConditionalOnProperty(
prefix = "spring.http.encoding",
value = {"enabled"},
matchIfMissing = true
) //判断配置文件中是否存在某个配置; 检查是否存在spring.http.encoding.enabled, 如果不存在则值默认为true
public class HttpEncodingAutoConfiguration {

HttpProperties:

1
2
3
4
5
6
7
8
9
10
11
@ConfigurationProperties(prefix = "spring.http")
public class HttpProperties {

//下面的成员变量即是配置文件中可配置的属性
public static class Encoding {
public static final Charset DEFAULT_CHARSET;
private Charset charset; //spring.http.encoding.charset=
private Boolean force; //spring.http.encoding.force=
private Boolean forceRequest; //spring.http.encoding.forceRequest=
private Boolean forceResponse; //spring.http.encoding.forceResponse=
private Map<Locale, Charset> mapping;

SpringMVC中的@Conditional有很多扩展
如: ConditionalOnJava, ConditionalOnClass

如何查看哪些自动配置类生效?(自动配置报告)

  1. 在application.properties中添加:
    debug=true
  2. 控制台会打出哪些自动配置类已经生效
    Positive matches: 下面所打印的记录为已经生效的自动配置类
    Negative matches: 下面锁打印的记录为未生效的自动配置类

SpringBoot Web开发

SpringBoot对静态资源的映射规则

自定义需继承:WebMvcConfigurationSupport类

原理:
WebMvcAutoConfiguration自动配置类

1
2
3
4
5
6
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
  1. 第一种方式: WebMvcAutoConfiguration自动配置类中的addResourceHandlers方法内部
    1
    2
    3
    if(!registry.hasMappingForPattern("/webjars/**")) {
    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }

可以看出:
如果访问路径为ip:port/webjars/xxx则会加载classpath:/META-INF/resources/webjars/路径下的文件
webjars: 以jar包的方式方式引入
参考地址: www.webjars.org

  1. 第二种方式: addResourceHandlers方法内部
    1
    2
    3
    4
    String staticPathPattern = this.mvcProperties.getStaticPathPattern();	// this.staticPathPattern = "/**";
    if(!registry.hasMappingForPattern(staticPathPattern)) {
    this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
    }

“/**”: 访问当前项目的任何资源, 如果没人处理则默认获取getResourceLocations, resourceLocations为classpath:/META-INF/resources/“, “classpath:/resources/“, “classpath:/static/“, “classpath:/public/, “/“
上面几个文件夹成为静态资源的文件夹
※resource是类路径的根目录 即 classpath

  1. 欢迎页: 静态资源文件夹下所有的index.html页面, 被”/**”映射
    例如: 访问ip:port/, 则会寻找index.html

    1
    2
    3
    4
    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
    return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
    }
  2. 图标

    1
    2
    3
    4
    5
    6
    7
    @Bean
    public SimpleUrlHandlerMapping faviconHandlerMapping() {
    SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
    mapping.setOrder(-2147483647);
    mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
    return mapping;
    }

所有的”**/favicon.ico”都在静态资源文件夹下找

可以在配置文件中使用spring.resource.static-locations=classpath:/hello/,classpath:/styy/ 来改变静态资源文件夹的位置

Thymeleaf模板引擎

作用
将模板和数据生成一个最终网页

1)、引入thymeleaf3

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

//在properties标签中增加, 指定最新版本thymeleaf
<thymeleaf.version>3.0.11.RELEASE</thymeleaf.version>
<!-- 布局功能的支持程序 thymeleaf3主程序 layout2以上版本 -->
<thymeleaf-layout-dialect.version>2.3.0</thymeleaf-layout-dialect.version>

2)、在html文件中导入thymeleaf命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">

3)、使用thymeleaf语法

语法规则
1)、 th:任意html属性

2)、表达式
${}: 获取变量值(支持OGNL: 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性

  1. 获取对象的属性、调用方法
  2. 使用内置的基本对象 -> 强悍
  3. 内置的一些工具对象)

*{}: 变量选择表达式, 和${}功能一样, 多了一个小功能

此处*{firstName}相当于${session.user.firstName}

#{}: 取国际化内容

@{}: 定义url连接
如果链接需要拼接的时候:
th:href="@{http://localhost/order(id=${id},age=${age})}" //简化传值 ?id=1&age=2
th:href="@{/order(id=${id},age=${age})}" //可以简化成这样

~{}: 片段应用表达式

行内写法:
[[]]: 相当于th:text, [[${id}]]

SpingMVC自动配置原理

以下是SpringBoot对SpringMVC的默认配置:

  • 自动配置了ViewResolver(视图解析器: 根据方法的返回值得到视图对象(view), 视图对象决定是转发到页面还是重定向到页面等)
    • WebMvcAutoConfiguration类里面有个ContentNegotiatingViewResolver的Bean, 用于组合所有的视图解析器
    • 如果想要自己定制, 则可以将自己的视图解析器加到容器中即可
  • Convert组件: 转换器
    • public String hello(User user): 类型转换使用Convert
    • 需要定制自己的转换器同上
  • Formatter: 格式化器
    • 2018/12/12 === Date
    • 需要定制自己的格式化器同上
  • HttpMessageConverters: SpringMVC用来转换Http请求和相应的
    • 例如返回User对象想用JSON方式的格式传出去, 那么就需要以json方式送出去的HttpMessageConverters
    • 需要定制则同上
  • MessageCodesResolver: 定义错误代码生成规则
  • ConfigurableWebBindingInitializer: 初始化web数据绑定器
    • 需要定制则同上

如何修改SpringBoot的默认配置

SpringBoot在自动配置很多组件的时候, 先看容器中有没有用户自定义的(@Bean, @Component)组件, 如果有就用用户配置的, 如果没有, 才自动配置. 某些组件可以同时存在多个, 如(ViewResolver等)

CATALOG
  1. 1. SpringBoot基础学习
    1. 1.1. 配置学习
      1. 1.1.1. @Value与@ConfigurationProperties的区别
      2. 1.1.2. @PropertySource和@ImportResource
      3. 1.1.3. SpringBoot中推荐的添加组件方式: 使用全注解方式
      4. 1.1.4. 随机数与占位符
      5. 1.1.5. 多环境配置
      6. 1.1.6. 配置文件加载的优先级
      7. 1.1.7. 外部配置文件的优先级
      8. 1.1.8. 配置加载原理
    2. 1.2. SpringBoot Web开发
      1. 1.2.1. SpringBoot对静态资源的映射规则
      2. 1.2.2. Thymeleaf模板引擎
    3. 1.3. SpingMVC自动配置原理
      1. 1.3.1. 以下是SpringBoot对SpringMVC的默认配置:
      2. 1.3.2. 如何修改SpringBoot的默认配置