SpringBoot入门
一:SpringBoot的简介
1.简化Spring应用的开发的一个框架
2.整个Spring技术栈的一大整合
3.J2EE开发的一站式解决方案
##SpringBoot优点:
- 快速创建独立运行的zspring项目以及主流框架的集成
- 使用嵌入式的Servlet容器,应用无需达成WAR包
- starters自动依赖与版本控制
- 大量的自动配置,简化开发,也可以修改默认值
- 无需配置XML,无代码生成,开箱即用
- 准生产环境的运行时应用监控
- 与云计算的天然集成
微服务
2014,martin fowler
微服务 :架构风格
一个应用应该是小型服务;可以通过HTTP的方式进行交互
每一个功能元素最终都是一个可独立替换和独立升级的软件单元
@SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,
SpringBoot就应该运行这个类的main方法来启动SpringBoot应用
SpringApplication.run(主程序类名.class,args);
-
@SpringBootConfiguration:Spring Boot配置类
标注在某个类上,表示这是一个Spring Boot的配置类;
@Configuration:配置类上来标注这个注解
配置类 -----配置文件 配置类也是容器中的一个组件:@Component -
@EnableAutoConfiguration:开启自动配置功能
以前我们需要配置的东西,Spring Boot帮我们开启自动配置;
@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;@AutoConfigurationPackage @Import({EnableAutoConfigurationImportSelector.class}) public @interface EnableAutoConfiguration {
-
AutoConfigurationPackage:自动配置包
@Import({Registrar.class})
Spring的底层注解@import,给容器导入一个组件;导入的组件由{Registrar.class};将主配置类(@SpringBootApplication标注的类)的所在的包及下面所有子包里面所有的组件扫描到Spring容器;- Import(EnableAutoConfigurationImportSelector.class);
给容器中导入组件?
EnableAutoConfigurationImportSelector:导入那些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加搭配容器里
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,并配置好这些组件;
有了自动配置类,免去了我们手动编写配置注入功能组件等的工作 - SpringFactoriesLoader。loadFactoryName(EnableAutoConfiguration.class,classLoader);
spring Boot 在启动的时候从类路径下的META-INF/spring.factories获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作以前我们需要自己配置的东西,自动配置类都帮我们;
- Import(EnableAutoConfigurationImportSelector.class);
J2EE的整体整合解决方案和自动配置都在E:\jar\maven_repository\maven_repository\org\springframework\boot\spring-boot-autoconfigure\1.5.9.RELEASE\spring-boot-autoconfigure-1.5.9.RELEASE.jar
Hello World探究
1.POM文件
1.父项目
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
</parent>
他的父项目:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath>../spring-boot-dependencies</relativePath>
</parent>
注:他来真正管理Spring Boot应用里面的所有依赖版本
Spring Boot的版本仲裁中心;
以后我们导入以来默认是不需要写版本;(没有在dependencies里面管理的依赖自然需要声明版本号)
2.导入的依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
spring-boot-starter-web:
- spring-boot-starte:spring-boot场景启动器;帮我们导入了web模板正常运行所以来的组件;
- Spring Boot将所有的功能场景都抽取出来,做成一个个starters(启动器),只需要在项目里面引入这些starter相关场景的所有依赖都会导入进来,要用什么功能就导入什么场景的启动器
使用Spring Initializer快速创建Spring Boot项目
@RestController是//@Controller@ResponseBody(//这个类所有的方法返回的数据直接写给浏览器(如果是对象转为json数据))的合体
IDE都支持使用Spirng的项目创建向导快速创建一个Spring Boot项目;
选择我们需要的模块;向导会联网创建Spring Boot项目;
默认生成的Spring Boot项目;
- 主程序已经生成好了,我们只需要我们自己的逻辑
- resources文件夹中的目录结构
- static:保存所有的静态资源;js css images
- templates:保存所有的模板页面;(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面);可以使用模板引(freemarker,thymeleaf)
- application.properties:Spring Boot应用的配置文件; 可以修改一些默认设置
二 Spring Boot配置
- Spring Boot使用一个全局的配置文件,配置文件名是固定的
- application.properties
- application.yml
❤:配置文件的作用:修改SpringBoot自动配置的默认值;
SpringBoot在底层都给我们配置好;
- 配置文件放在src/main/resources目录或者类路径/config下
- .yml是YAML(YAML Ain`t Markup Language)语言的文件,以数据为中心,比json,xml等更适合做配置文件
- 全局的配置文件可以对一下默认值进行修改
YAML Ain`t Markup Language
- YAML A Markup Language :是一个标记语言
- YAML isn`t Markup Language:不是一个标记语言
标记语言:
- 以前的配置文件:大多都是使用xxx.xml文件
- YAML:以数据为中心,比json,xml等更适合做配置文件
YAML语法
1.YAML基本语法
k:(空格)v:表示一对键值对(空格必须有)
- 使用缩进表示层级关系;只要是左对齐的一列数据,都是同一级的
- 缩进时不允许使用Tab键,只允许使用空格
- 缩进的空格数目不重要,只要相同层级的元素左侧对其即可
- 属性和值大小写敏感
2.YAML支持的三种数据结构
- 对象(属性和值):键值对的集合
- 数组:一组按次序排列的值
- 字面量:单个的,不可再分的值(数字,字符串,布尔)
k:v :字面直接来写;
字符串默认不要加上单引号或者双引号
“”:双引号不会转义字符串里面的特殊字符;特殊字符会作为本身想表示的意思
‘’:单引号 会转义特殊字符,特殊字符最终只是一个普通的字符串数据
对象,Map(属性和值)(键值对):
k:v:
对象还是k:v的方式
friends:
lastName:zhangsan
age:20
行内写法:
friends:{lastName:zhangsan,age:18}
数组(list,Set)
用**-空格**值表示数组中的一个元素
pets:
- cat
- dog
- pig
行内写法
pets:[cat,dog,pig]
将配置文件中配置的每一个属性的值,映射到这个组件中
@ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中得相关的配置进行绑定;
只有这个组件是容器中的组件,才能使用容器提供的@Configurationproperties功能
需要加一个@Component
prifix=“person” 配置文件中那个下面属性进行一一映射
默认从全局配置文件中获取值
导入配置文件处理器,配置文件进行绑定就会有提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2.@value获取值和@ConfigurationProperties获取值比较
@ConfigurationProperties | @value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散语法绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
配置文件yml还是properties他们都能获取到值;
如果说,我们只是在某个业务逻辑中需获取一下配置文件中的某项值,使用@Value;
如果说,我们专门编写了一个JavaBean来和配置文件进行映射,我们就直接使用
@ConfigurationProperties
- @PropertySource(value={“classpath:”})读取类路径下指定的文件
- @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
Spring Boot里面没有Spring的配置文件,我们字节编写的配置文件,也不能自动识别;想让Spring的配置文件生效,加载进来,需要**@ImportResource**标注在一个配置类上
Spring Boot推荐给容器中添加组件的方式:推荐使用全注解的方式
- 配置类========配置文件 @Configuration:指明当前类是一个配置类;就是来替换之前Spring配置文件
- @Bean 将方法的返回值添加到容器中,容器中这个组件默认的id就是这个的方法名
配置文件占位符
-
RandomValuePropertySource:配置文件中可以使用随机数
- ${random.value}
- ${random.int}
- ${random.long}
- ${random.int(10)}
- ${random{1024,65536}}
-
属性配置占位符
app.name=MyApp
app.description=${app.name} is a Spring Boot application- 可以在配置文件中引用前面配置过的属性(优先级前面配置过得这里都能用)
- ${app.name:默认值} 来指定找不到属性时的默认值
Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活,指定参数等方式快速切换环境
1.多Profile文件形式
我们可以在主配置文件编写的时候,文件名可以是application-{profile}.properties/yml
默认使用application.properties的配置
- 格式:application-{profile}.properties:
- application-dev.properties,application-prod.properties
2.多profile文档块模式:
3.激活方式:
- 命令行 --spring.profiles.active=dev
- 在配置文件中指定 spring.profiles.active=dev
- 配置文件 spring.profiles.active=dev
- jvm参数 -Dspring.profiles.active=dev
配置文件加载位置
- spring boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring Boot的默认配置文件
- file:/config/
- file:./
- classpath:/config
- classpath:/
- 以上时按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容
- 我们也可以通过配置spring.config.location来改变默认配置,项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置;
- SpringBoot会从这四个位置全部加载主配置文件;互补配置
外部配置加载顺序
Spring Boot支持多种外部配置的顺序
springBoot也课题从以下位置加装配置;优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置形成互补配置
- 命令行参数
- 来自java:comp/env的JND属性
- Java系统属性(System.getProperties())
- 操作系统环境变量
- RandomValuePropertySource配置的random.*属性值
- 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)配置文件
- @Configuration注解类上的@propertySource
- 通过SpringApplication.setdefaultProperties指定的默认文件
注:由jar包外向jar包内寻找;优先加装带profile
多个配置用空格分开: --配置项=值
自动配置原理
- 1.SpringBoot启动的时候加载主配置类,开启了自动配置功能==@EnableAutoConfiguration==
- 2.@EnableAutoConfiguration作用
-
利用 EnableAutoConfigurationImportSelectorgeoron给容器中导入一些组件
-
可以查看selectImports()方法的内容;
-
List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置
- SpringFactoriesLoader.loadFactoryNames
- 扫描所有jar包类路径下META-INF/spring.factories
- 把扫描到的这些文件的内容包装成properties对象
- 从properties中获取EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加到容器中
将类路径下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中
-
每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置
-
3.每一个自动配置类进行自动配置功能
-
4.以 HTTPEnableAutoConfiguration(http编码自动配置)为例解释自动配置原理:
@Configuration( == //表示这是一个配置类,以前编写的配置文件一样,也可以给容器添加组件==
proxyBeanMethods = false
)
@EnableConfigurationProperties({HttpEncodingProperties.class}) //启用指定类的ConfigurationProperries功能;将配置文件中对应的值和HttpEncodingProperties绑定起来,并把HttpEncodingProperties加入到ioc容器中
@ConditionalOnWebApplication( //spring底层@Conditional注解根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会生效 ; 判断当前应用是否是web应用,如果是当前配置类生效
type = Type.SERVLET
)
@ConditionalOnClass({CharacterEncodingFilter.class}) //判断当前项目有没有这个类
CharacterEncodingFilter:SpringMVC中进行乱码解决的过滤器
@ConditionalOnProperty( // 判断配置文件中是否存在某个配置spring.http.encoding.enable; 如果不存在,判断也成立
即使我们配置文件中不配置 // spring.http.encoding.enable=ture 也是默认生效
prefix = “spring.http.encoding”,
value = {“enabled”},
matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {他已经和Sopringboot的配置文件映射了
private final Encoding properties;只有一个有参构造器的情况下,参数的值就会从容器里拿
public HttpEncodingAutoConfiguration(HttpProperties properties) {
this.properties = properties.getEncoding();
}@Bean 给容器中添加一个组件,这个组件的值需要从properties中获取
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() {
CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
filter.setEncoding(this.properties.getCharset().name());
filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
return filter;
}
根据当前不同的条件判断,决定这个配置类是否生效?
一旦这个配置类生效;这个配置类就会给容器中添加各种组件;这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性
又和配置文件绑定的;
- 5.所有在配置文件中能配置的属性都是在xxxProperties类中封装着;配置文件能配置什么就可以参照某个功能对应的这个属性类
>@ConfigurationProperties( //从配置文件中获取指定的值和bean的属性继续绑定
prefix = "spring.http"
)<
精髓:
1.SpringBoot启动会加载大量的配置类
2.我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
3.我们再来开这个自动配置类中到底配置了那些组件(只要我们要用的组件有,我们就不需要再来配置了)
4.给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值
xxxAutoConfiguration:制动配置类
给容器中添加组件
xxxProperties:封装配置文件中相关的属性
##细节
1.@Conditional派生注解
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置类里面的所有内容才会生效
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否满足条件 |
@ConditionalOnBean | 容器中存在指定Bean |
@ConditionalOnMissingBean | 容器中不存在指定Bean |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统有指定类 |
@ConditionalOnMissingClass | 系统中没有指定类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定Bean或者这个Bean是首选的Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否有指定的资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是webn环境 |
@ConditionalOnJndi | JNDI存在指定项 |
开启SpringBoot的debug
application.properties中写入debug=true来让控制台打印自动配置报告,这样就能很方便知道哪些自动配置生效
自动配置类必须在一定的条件下才能生效
Positive matches:(自动配置类启用的)
Nrgative mathes:(没有启动,没有匹配成功的自动配置类)
三 日志
SpringBoot
日志门面(日志的抽象层):SLF4J
日志实现:Logback
SLF4j使用
1.如何在系统中使用SLF4j
以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;
给系统里面导入slf4j的jar和logback的实现jar
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
每一个日志的实现框架都有自己的配置文件。使用slf4j以后,配置文件还是做成日志实现框架自己本身的配置文件
统一日志记录,及识别的框架和我一起同意使用slf4j进行输出?
如何让系统中所有的日志都统一到slf4j
- 将系统中其他日志框架先排除出去
- 用中间包来替换原有的日志框架
- 我们导入slf4j其他的实现
SpringBoot中的日志关系
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
springBoot使用他来做日志功能
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
总结
- SpringBoot地层也是使用slf4j+logback的方式进行日志记录
- SpringBoot也把其他的日志都替换成了slf4j
- 中间替换包
- 如果我们要引入其他的框架,一定要把这个框架的默认日志依赖移除掉
SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架的日志框架移除掉
日志的使用
记录器
Logger logger =LoggerFactory.getLogger(getClass());
日志的级别
由低到高 trace<debug<info<warn<error
可以调整输出的日志级别;日志就只会在这个级别之后的高级别生效
springBoot默认给我们使用的是info级别的;没有指定级别的就用S平日ingBoot默认规定的级别;root级别
日志输出格式:
- %d表示时间
- %thread表示线程名
- %-5level:级别从做显示五个字符宽度
- %logger{50}表示logger名字长50个字符,否者按句号点分割
- %msg:日志信息
- %n是换行符
- %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -%msg%n
不指定路径在当前项目下生成springboot.log日志
可以指定完整的路径
logging.file=
在控制台输出日志的格式
logging.pattern.console=
指定文件中日志输出的格式
logging.pattern.file=
指定位置
给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不会使用其他的默认配置
Logging System | Customization |
---|---|
Logback | logback-spring.xml ,logback-spring.groovy,logback.xml or logback.groovt |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK(Java Util Logging) | logging.properties |
logback.xml:直接就被日志框架识别了
logback-spring.xml:日志框架就不直接加载日志的配置项,由springboot解析日志配置,可以使用SpringBoot的高级profile功能
<springProfile name="staging">
<!--configuration to be enable when the "staging" profile is active-->
可以指定某段配资只在某个环境下生效
</springProfile>
否则
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<!--
日志输出格式:
%d表示日期时间,
%thread表示线程名,
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长50个字符,否则按照句点分割。
%msg:日志消息,
%n是换行符
-->
<layout class="ch.qos.logback.classic.PatternLayout">
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
</springProfile>
</layout>
</appender>
四,Spring Boot与web开发
使用SpringBoot
- 创建一个SpringBoot应用,选中我们需要的模块;
- SpringBoot已经默认将这些场景配置好了,只需要在配置文件中制定少量配置就可以运行起来
- 自己编写业务代码
自动配置原理?
这个场景SpringBoot帮我们配置什么?能不能修改?能修改那些配置?能不能扩展?xxx
- xxxxAutoConfiguration:帮我们给容器中自动配置组件
- xxxxproperties:配置类来封装配置文件的内容
SpringBoot对静态资源的映射规则
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
可以设置静态资源的有关的参数,缓存时间等
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
//配置欢迎页映射
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext) {
return new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext),
applicationContext, getWelcomePage(), this.mvcProperties.getStaticPathPattern());
}
@Configuration
@ConditionalOnProperty(value = "spring.mvc.favicon.enabled", matchIfMissing = true)
public static class FaviconConfiguration implements ResourceLoaderAware {
private final ResourceProperties resourceProperties;
private ResourceLoader resourceLoader;
public FaviconConfiguration(ResourceProperties resourceProperties) {
this.resourceProperties = resourceProperties;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Bean
public SimpleUrlHandlerMapping faviconHandlerMapping() {
SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1);
mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", faviconRequestHandler()));
return mapping;
}
//配置喜欢的图标
@Bean
public ResourceHttpRequestHandler faviconRequestHandler() {
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
requestHandler.setLocations(resolveFaviconLocations());
return requestHandler;
}
private List<Resource> resolveFaviconLocations() {
String[] staticLocations = getResourceLocations(this.resourceProperties.getStaticLocations());
List<Resource> locations = new ArrayList<>(staticLocations.length + 1);
Arrays.stream(staticLocations).map(this.resourceLoader::getResource).forEach(locations::add);
locations.add(new ClassPathResource("/"));
return Collections.unmodifiableList(locations);
}
}
}
-
所有/webjars/**,都去classpath:/META-INF/resources/webjars/找资源
webjars:以jar包的方式引入静态资源 -
“/**” 访问当前项目的任何资源(静态资源文件夹)
- “classpath:/META-INF/resources/”,
- “classpath:/resources/”,
- “classpath:/static/”,
- “classpath:/public/”
- “/”:当前项目下的根路径
localhost:8080/abc === 去静态资源文件夹下找abc
-欢迎页;静态资源文件夹下的所有index.html页面;被"/**"映射;
localhost:8080/ 找index页面
-
所有的"**/favicon.ico"都是在静态文件夹下找
模板引擎
JSP VElocity Freemarker Thymeleaf
SpringBoot推荐的Thymeleaf
语法更简单,功能更强大
1.引入Thymeleaf
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2.Thymeleaf使用&语法
@ConfigurationProperties(prefix = "spring.thymeleaf")
public class ThymeleafProperties {
private static final Charset DEFAULT_ENCODING = StandardCharsets.UTF_8;
public static final String DEFAULT_PREFIX = "classpath:/templates/";
public static final String DEFAULT_SUFFIX = ".html";
只要我们把html页面放在classpath:/templates/,thymeleaf就能自动渲染
使用:
- 导入thtmeleaf的名称空间
- 语法
- th:text 将div里面的文本内容设置为
语法规则
1.th:text 改变当前元素里面的文本内容;
th:任意html属性;来替换原生属性的值
2.表达式
❤Simple expressions:
Variable Expressions: ${...} 获取变量值;OGNL;
1.获取对象的属性,调用方法
2.使用内置的基本对象
#ctx : the context object.
#vars: the context variables.
#locale : the context locale.
#request : (only in Web Contexts) the HttpServletRequest object.
#response : (only in Web Contexts) the HttpServletResponse object.
#session : (only in Web Contexts) the HttpSession object.
#servletContext : (only in Web Contexts) the ServletContext object
3.内置的一些工具对象
#execInfo : information about the template being processed.
#messages : methods for obtaining externalized messages inside variables expressions, in the same way as they
would be obtained using #{…} syntax.
#uris : methods for escaping parts of URLs/URIs
Page 20 of 106
#conversions : methods for executing the configured conversion service (if any).
#dates : methods for java.util.Date objects: formatting, component extraction, etc.
#calendars : analogous to #dates , but for java.util.Calendar objects.
#numbers : methods for formatting numeric objects.
#strings : methods for String objects: contains, startsWith, prepending/appending, etc.
#objects : methods for objects in general.
#bools : methods for boolean evaluation.
#arrays : methods for arrays.
#lists : methods for lists.
#sets : methods for sets.
#maps : methods for maps.
#aggregates : methods for creating aggregates on arrays or collections.
#ids : methods for dealing with id attributes that might be repeated (for example, as a result of an iteration).
Selection Variable Expressions: *{...} 选择表达式:和${}在功能上一样;
❤补充:配合 th:object="${session.user}"
<div th:object="${session.user}">
<p>Name: <span th:text="*{firstName}">Sebastian</span>.</p>
<p>Surname: <span th:text="*{lastName}">Pepper</span>.</p>
<p>Nationality: <span th:text="*{nationality}">Saturn</span>.</p>
</div>
Message Expressions: #{...} 获取国际化内容
Link URL Expressions: @{...} 定义URL
@{/order/process(execId=${execId},execType='FAST')}
Fragment Expressions: ~{...} 片段引用表达式
<div th:insert="~{commons :: main}">...</div>
❤Literals (字面量)
Text literals: 'one text' , 'Another one!' ,…
Number literals: 0 , 34 , 3.0 , 12.3 ,…
Boolean literals: true , false
Null literal: null
Literal tokens: one , sometext , main ,…
❤Text operations: (文本操作)
String concatenation: +
Literal substitutions: |The name is ${name}|
❤Arithmetic operations:(数学运算)
Binary operators: + , - , * , / , %
Minus sign (unary operator): -
❤Boolean operations:(布尔运算)
Binary operators: and , or
Boolean negation (unary operator): ! , not
❤Comparisons and equality:(比较运算)
Comparators: > , < , >= , <= ( gt , lt , ge , le )
Equality operators: == , != ( eq , ne )(三元运算符)
❤Conditional operators:(条件运算)
If-then: (if) ? (then)
If-then-else: (if) ? (then) : (else)
Default: (value) ?: (defaultvalue)
❤Special tokens:(特殊操作)
No-Operation
SpringMVC自动配置
27.1.1 Spring MVC auto-configuration
Spring Boot 自动配置好了SpringMVC
以下是SpringBoot对SpringMVC的默认
Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
❤自动配置了ViewResolver (视图解析器:根据方法的返回值得到视图对象(View),视图对象绝对如何渲染(转发?重定向))
❤ContentNegotiatingViewResolver:组合所有的视图解析器
❤如何定制:我们可以自己给容器中添加一个视图解析器;自动的将其组合起来
Support for serving static resources, including support for WebJars (see below).
自动注册了 of Converter, GenericConverter, Formatter beans.
❤Converter:转换器;public String hello(User user):类型转换使用
❤Formatter 格式化器 2017-12-17===Date
❤自己添加的格式转换器,我们只需要放在容器中即可
Support for HttpMessageConverters (see below).
❤HttpMessageConverters:SpringMVC用来转换Http请求和响应的User---Json
❤HttpMessageConverters是从容器中确定的,获取所有的HttpMessageConverters
❤自己给容器中添加HttpMessageConverters只需要将自己的组件注册到容器中(@Bean,@Component)
Automatic registration of MessageCodesResolver (see below).定义错误代码生成规则
Static index.html support. 静态首页访问
Custom Favicon support (see below). 静态资源文件夹路径,webjars
Automatic use of a ConfigurableWebBindingInitializer bean (see below).
❤初始化WebDateBinder 数据绑定器
❤请求数据===JavaBean
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
扩展SpringMVC
编写一个配置类(@Configuation) ,是WebMvcConfigurerAdapter类型;不能标注@EnableWebMvc
既保留看所有的自动配置,也能用我们扩展的配置
原理:
1.WebMvcAutoConfiguration是SpringMvc的自动配置类
2.在做其他自动配置时会导入@Import(EnableWebMvcConfiguration.class)
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
//从容器中获取所有的WebMvcConfigurer
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
//一个参考实现,将所有的WebMvcConfigurer相关配置都来一起调用
@Override
public void addFormatters(FormatterRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addFormatters(registry);
}
}
}
}
3.容器中所有耳朵WebMvcConfigurer都会起作用
4.我们的配置类也会被调用
效果:SpringMvc的自动配置也会和我们的扩展配置都会作用
全面接管SpringMVC
SpringBoot对SpringMVC的自动配置不需要了,所有的都是我们自己配;所有的SpringMvc场景自动配置都失效
我们只需要在配置类中添加@EnableWebMvc即可;
原理:
为什么@EnableWebMvc自动配置就失效了
1.@EnableWebMvc核心
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
2.、
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) //容器中没有这个组件的时候,这个自动配置类才生效
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
4.@EnableWebMvc将WebMvcConfigurationSupport组件导入进来;
5.导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能
如何修改SpringBoot的默认配置
模式:
1.SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean,@Component)
如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置和自己
默认的组合起来
2.在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置
RestfulCRUD
1.默认访问首页
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
//@EnableWebMvc 不要接管SpringMVC
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
//所有的WebMvcConfigurerAdapter组件都会一起起作用
@Bean //将组件注册在容器
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
}
};
return adapter;
}
}
国际化
1.编写国际化配置文件
2.使用ResourceBundleMessageSource管理国际化资源文件
3.在页面使用fmt:message取出国际化内容
步骤
1.编写国际化配文件,抽取页面需要显示的国际化消息
定制错误页面
原理
可以参考ErrorMVCAutoConfiguration;错误处理的自动配置
给容器中添加了一下组件
1.DefaultErrorAttribute
2.BasicErrorController
3.ErrorPageCustomizer
4.DefaultErrorViewResolver
步骤:
·一旦系统出现4xxx或者5xx之类的错误;ErrorPageCustomizer就会生效()