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
"classpath:person.properties"}) (value = {
@ImportResource
作用: 导入Spring的配置文件, 让配置文件里面的内容生效
自己编写的配置文件(xml文件), 无法自动识别, 如果想让Spring的配置文件生效, 则使用@ImportResource标注在启动类上
用法:1
"classpath:beans.xml"}) (localtions = {
SpringBoot中推荐的添加组件方式: 使用全注解方式
创建一个配置类1
2
3
4
5
6
7
8
9//标明当前是个配置类
public class MyAppConfig {
//将方法的返回值添加到容器中; 容器中这个组件默认的id就是方法名, 相当于配置文件中的<bean>
public HelloService helloService(){
return new HelloService();
}
}
随机数与占位符
随机数
用法:1
${random.int}, ${random.uuid}等
占位符
用法:1
2
3person.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 | server: |
方法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)配置文件
配置加载原理
- @SpringBootApplication
- @EnableAutoConfiguration
- AutoConfigurationImportSelector
- selectImports方法
- getAutoConfigurationEntry方法
- getCandidateConfigurations方法
- loadFactoryNames方法
- loadSpringFactories方法
- 扫描所有jar包类路径下 META-INF/spring.factories
- 把扫描到的这些文件的内容包装秤properties对象
- 从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//表示这是一个配置类
//启动指定类的ConfigurationProperties功能, 将配置文件中的值和HttpProperties绑定起来 ({HttpProperties.class})
//判断当前应用是否为Web应用, 如果为Web应用则配置类的配置生效 (type = Type.SERVLET)
//判断当前项目是否有CharacterEncodingFilter类:SpringMVC中进行乱码解决的过滤器 ({CharacterEncodingFilter.class})
(
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"spring.http") (prefix =
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
如何查看哪些自动配置类生效?(自动配置报告)
- 在application.properties中添加:
debug=true
- 控制台会打出哪些自动配置类已经生效
Positive matches: 下面所打印的记录为已经生效的自动配置类
Negative matches: 下面锁打印的记录为未生效的自动配置类
SpringBoot Web开发
SpringBoot对静态资源的映射规则
自定义需继承:WebMvcConfigurationSupport类
原理:
WebMvcAutoConfiguration自动配置类
1 | ( |
- 第一种方式: WebMvcAutoConfiguration自动配置类中的addResourceHandlers方法内部
1
2
3if(!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
- 第二种方式: addResourceHandlers方法内部
1
2
3
4String 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
欢迎页: 静态资源文件夹下所有的index.html页面, 被”/**”映射
例如: 访问ip:port/, 则会寻找index.html1
2
3
4
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
}图标
1
2
3
4
5
6
7
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 | <dependency> |
2)、在html文件中导入thymeleaf命名空间<html lang="en" xmlns:th="http://www.thymeleaf.org">
3)、使用thymeleaf语法
语法规则
1)、 th:任意html属性
2)、表达式
${}: 获取变量值(支持OGNL: 通过它简单一致的表达式语法,可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性
- 获取对象的属性、调用方法
- 使用内置的基本对象 -> 强悍
- 内置的一些工具对象)
*{}: 变量选择表达式, 和${}功能一样, 多了一个小功能
此处*{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等)