SpringBoot学习记录

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指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作以前我们需要自己配置的东西,自动配置类都帮我们;

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

  1. @PropertySource(value={“classpath:”})读取类路径下指定的文件
  2. @ImportResource:导入Spring的配置文件,让配置文件里面的内容生效;
    Spring Boot里面没有Spring的配置文件,我们字节编写的配置文件,也不能自动识别;想让Spring的配置文件生效,加载进来,需要**@ImportResource**标注在一个配置类上

Spring Boot推荐给容器中添加组件的方式:推荐使用全注解的方式

  1. 配置类========配置文件 @Configuration:指明当前类是一个配置类;就是来替换之前Spring配置文件
  2. @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也课题从以下位置加装配置;优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置形成互补配置

  1. 命令行参数
  2. 来自java:comp/env的JND属性
  3. Java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. RandomValuePropertySource配置的random.*属性值
  6. jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  7. jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
  8. jar包外部的application.properties或啊application.yml(不带spring.profile)配置文件
  9. jar包内部的application.properties或啊application.yml(不带spring.profile)配置文件
  10. @Configuration注解类上的@propertySource
  11. 通过SpringApplication.setdefaultProperties指定的默认文件

注:由jar包外向jar包内寻找;优先加装带profile
多个配置用空格分开: --配置项=值

自动配置原理

  • 1.SpringBoot启动的时候加载主配置类,开启了自动配置功能==@EnableAutoConfiguration==
  • 2.@EnableAutoConfiguration作用
    • 利用 EnableAutoConfigurationImportSelectorgeoron给容器中导入一些组件

    • 可以查看selectImports()方法的内容;

    • List configurations = this.getCandidateConfigurations(annotationMetadata, attributes);获取候选的配置

      1. SpringFactoriesLoader.loadFactoryNames
      2. 扫描所有jar包类路径下META-INF/spring.factories
      3. 把扫描到的这些文件的内容包装成properties对象
      4. 从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环境
@ConditionalOnJndiJNDI存在指定项

开启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

  1. 将系统中其他日志框架先排除出去
  2. 用中间包来替换原有的日志框架
  3. 我们导入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>

总结

  1. SpringBoot地层也是使用slf4j+logback的方式进行日志记录
  2. SpringBoot也把其他的日志都替换成了slf4j
  3. 中间替换包
  4. 如果我们要引入其他的框架,一定要把这个框架的默认日志依赖移除掉

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 SystemCustomization
Logbacklogback-spring.xml ,logback-spring.groovy,logback.xml or logback.groovt
Log4j2log4j2-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

  1. 创建一个SpringBoot应用,选中我们需要的模块;
  2. SpringBoot已经默认将这些场景配置好了,只需要在配置文件中制定少量配置就可以运行起来
  3. 自己编写业务代码

自动配置原理?
这个场景SpringBoot帮我们配置什么?能不能修改?能修改那些配置?能不能扩展?xxx

  1. xxxxAutoConfiguration:帮我们给容器中自动配置组件
  2. 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就会生效()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值