欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

springboot2

时间:2023-06-16

SpringBoot2核心技术与响应式编程 · 语雀 (yuque.com)https://www.yuque.com/atguigu/springboot


基础入门 

        java8        maven3.3+ 一、HelloWorld

Getting Started (spring.io)https://docs.spring.io/spring-boot/docs/current/reference/html/getting-started.html#getting-started.first-application1、新建maven工程

2、pom.xml

<?xml version="1.0" encoding="UTF-8"?> 4.0.0 com.ice springboot-01-helloworld 1.0-SNAPSHOT jar org.springframework.boot spring-boot-starter-parent 2.3.4.RELEASE org.springframework.boot spring-boot-starter-web

3、主程序

package com.ice.boot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;//主程序类@SpringBootApplication//标注这是一个springboot应用public class MainApplication { public static void main(String[] args) { //固定写法 SpringApplication.run(MainApplication.class,args); }}

        业务类:

package com.ice.boot.controller;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;@RestController//前两个的合体public class HelloController { @RequestMapping(value = "/hello") public String handle01(){ return "Hello, springboot 2 !"; }}

4、测试(直接运行主程序类里的主方法)

        神奇!

        不需要配置Tomcat! 

        控制台:

         浏览器:

5、简化配置

        application.properties:

Common Application Properties (spring.io)https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties

6、简化部署

        不需要配置Tomcat! 

        把项目打成jar包,直接在目标服务器执行即可。

        pom.xml中添加:

org.springframework.boot spring-boot-maven-plugin

        启动: 

 

        文件夹中有jar: 

 

        CMD运行: 

         浏览器中也能访问localhost://8080/hello

        注意:取消掉cmd的快速编辑模式

二、自动配置原理  2.1 springboot特点 2.1.1 依赖管理 

        父项目做依赖管理:几乎声明了所有开发中常用的依赖的版本号,自动版本仲裁机制        开发导入starter场景启动器:

Developing with Spring Boothttps://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter

1、见到很多 spring-boot-starter-* : *代表某种场景2、只要引入starter,这个场景的所有常规需要的依赖都自动引入3、SpringBoot所有支持的场景https://docs.spring.io/spring-boot/docs/current/reference/html/using-spring-boot.html#using-boot-starter4、见到的 *-spring-boot-starter: 第三方提供的简化开发的场景启动器。5、所有场景启动器最底层的依赖 org.springframework.boot spring-boot-starter 2.3.4.RELEASE compile

        无需关注版本号,自动版本仲裁

                1、引入依赖默认都可以不写版本
                2、引入非版本仲裁的jar,要写版本号。 

        可以修改默认版本号:

1、查看spring-boot-dependencies里面规定当前依赖的版本 用的 key。2、在当前项目pom.xml里面重写配置,自定义需要的版本号 5.1.43

2.1.2 自动配置

自动配好Tomcat:引入、配置(引入web场景依赖的时候Tomcat依赖已经被引入)自动配好SpringMVC:引入、自动配置常用组件(引入web场景依赖的时候SpringMVC依赖已经被引入)自动配好Web常见功能:SpringBoot配置好了所有web开发的常见场景,如以下:

//主程序类@SpringBootApplication//标注这是一个springboot应用public class MainApplication { public static void main(String[] args) { //固定写法 //1、返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } }}

         嗯,就是啥都帮你弄好了,啥都有。

         

默认的包结构:主程序所在包及其下面的所有子包里面的组件都会被默认扫描进来,不需要配置包扫描

        改变包扫描路径:

        (1)

         (2)

@SpringBootApplication等同于@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.ice.boot")

 各种配置拥有默认值

        1、默认配置最终都是映射到某个类上,如:MultipartProperties

        2、配置文件(application.properties)的值最终会绑定每个类上,这个类会在容器中创建对象

按需加载所有自动配置项

        1、非常多的场景starter

        2、引入了哪些场景这个场景的自动配置才会开启

        3、SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面

2.2 容器功能 2.2.1 组件添加

1、@Configuration

        Full模式与Lite模式

        实例:

@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件public class MyConfig { @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例 public User user01() { User zt = new User("zt", 23); //User组件依赖了Pet组件 zt.setPet(tomcatPet()); return zt; } @Bean("tom") public Pet tomcatPet() { return new Pet("tomcat"); }}

        测试:

        //4、

//主程序类@SpringBootApplication(scanbasePackages="com.ice")public class MainApplication { public static void main(String[] args) { //固定写法 //1、返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //3、从容器中获取组件 Pet tom01 = run.getBean("tom", Pet.class); Pet tom02 = run.getBean("tom", Pet.class); System.out.println("组件:"+(tom01 == tom02)); //4、com.ice.boot.config.MyConfig$$EnhancerBySpringCGLIB$$7dcb51b5@f91da5e MyConfig bean = run.getBean(MyConfig.class); System.out.println(bean); //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查在容器中是否有这个组件。 //保持组件单实例 User user = bean.user01(); User user1 = bean.user01(); System.out.println(user == user1); User user01 = run.getBean("user01", User.class); Pet tom = run.getBean("tom", Pet.class); System.out.println("用户的宠物:"+(user01.getPet() == tom)); }}

配置类组件之间无依赖关系用Lite模式加速容器启动过程,减少判断配置类组件之间有依赖关系,方法会被调用得到之前单实例组件,用Full模式

2、@Bean、@Component、@Controller、@Service、@Repository

3、@ComponentScan、@import 

        //5、获取组件

//主程序类;主配置类@SpringBootApplication(scanbasePackages="com.ice")public class MainApplication { public static void main(String[] args) { //固定写法 //1、返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } //3、从容器中获取组件 Pet tom01 = run.getBean("tom", Pet.class); Pet tom02 = run.getBean("tom", Pet.class); System.out.println("组件:"+(tom01 == tom02)); //4、com.ice.boot.config.MyConfig$$EnhancerBySpringCGLIB$$7dcb51b5@f91da5e MyConfig bean = run.getBean(MyConfig.class); System.out.println(bean); //如果@Configuration(proxyBeanMethods = true)代理对象调用方法。SpringBoot总会检查在容器中是否有这个组件。 //保持组件单实例 User user = bean.user01(); User user1 = bean.user01(); System.out.println(user == user1); User user01 = run.getBean("user01", User.class); Pet tom = run.getBean("tom", Pet.class); System.out.println("用户的宠物:"+(user01.getPet() == tom)); //5、获取组件 String[] names1 = run.getBeanNamesForType(User.class); for (String name1 : names1) { System.out.println(name1); } DBHelper bean1 = run.getBean(DBHelper.class); System.out.println(bean1); }}

        其他@import用法可参照 Spring注解驱动开发_m0_61922004的博客-CSDN博客

4. @Conditional

        条件装配:满足Conditional指定的条件,则进行组件注入

         *下面代码有些问题,应该先注册@Bean(“tom”)。否则先扫描user01,就算后面注册了tom,结果都还是false。组件注册顺序很重要(@ConditionalOnBean(name="tom")写在方法上时,注册tom写在注册user01后面,结果tom是true,而user01是false)!

        *试了一下,也不对……筛选条件在类上,符合条件的在类里面的方法上,都是false。@ConditionalOnBean(name="tom")放在类上好像没啥作用。

@import({User.class, DBHelper.class})@Configuration(proxyBeanMethods = true) //告诉SpringBoot这是一个配置类 == 配置文件@ConditionalOnBean(name="tom")//也可以标注在类上,容器中有tom组件时方法内部的标注才生效public class MyConfig { //@ConditionalOnBean(name="tom")//容器中没有tom这个组件了,也就不想要user01这个用户 @Bean //给容器中添加组件。以方法名作为组件的id。返回类型就是组件类型。返回的值,就是组件在容器中的实例 public User user01() { User zt = new User("zt", 23); //User组件依赖了Pet组件 zt.setPet(tomcatPet()); return zt; } //@Bean("tom") @Bean("tom1") public Pet tomcatPet() { return new Pet("tomcat"); }}

@SpringBootApplication(scanbasePackages="com.ice")public class MainApplication { public static void main(String[] args) { //固定写法 //1、返回IOC容器 ConfigurableApplicationContext run = SpringApplication.run(MainApplication.class, args); //2、查看容器里面的组件 String[] names = run.getBeanDefinitionNames(); for (String name : names) { System.out.println(name); } boolean tom = run.containsBean("tom"); System.out.println("容器中是否存在tom组件:"+tom); boolean user01 = run.containsBean("user01"); System.out.println("容器中是否存在user01组件:"+user01); boolean tom1 = run.containsBean("tom1"); System.out.println("容器中是否存在tom1组件:"+tom1); }}

2.2.2 原生配置文件引入

 @importResource

        如果以前有使用spring配置文件把bean配置到容器中(但是springboot不知道这个文件是干什么的),可以使用该注解,解析配置文件中的内容放到容器中

@importResource("classpath:beans.xml")public class MyConfig {}

2.2.3 配置绑定

        使用Java读取到properties文件中的内容,并且把它封装到JavaBean中,以供随时使用。以前的做法:

public class getProperties { public static void main(String[] args) throws FileNotFoundException, IOException { Properties pps = new Properties(); pps.load(new FileInputStream("a.properties")); Enumeration enum1 = pps.propertyNames();//得到配置文件的名字 while(enum1.hasMoreElements()) { String strKey = (String) enum1.nextElement(); String strValue = pps.getProperty(strKey); System.out.println(strKey + "=" + strValue); //封装到JavaBean。 } } }

1. @Component + @ConfigurationProperties

@Component@ConfigurationProperties(prefix = "mycar")public class Car { private String brand; private Integer price;

        application.properties中添加:

mycar.brand = mini Coopermycar.price = 300000

         测试:

@RestController//前两个的合体public class HelloController { //自动注入。因为类car上有@Component注解,已经加入IOC容器了 @Autowired Car car; @RequestMapping(value = "/car") public Car car(){ return car; } @RequestMapping(value = "/hello") public String handle01(){ return "Hello, springboot 2 !"+"周涛"; }}

2. @EnableConfigurationProperties + @ConfigurationProperties

@EnableConfigurationProperties(Car.class)public class MyConfig {

//@Component@ConfigurationProperties(prefix = "mycar")public class Car {

         启动报错,找不到Car这个bean……

        注释掉配置类MyConfig上的注解@ConditionalOnBean(name="tom")又启动成功了……

2.3 自动配置原理入门 2.3.1 引导加载自动配置类

//@SpringBootApplication(scanbasePackages="com.ice")相当于下面三个注解合起来@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan("com.ice")

@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan( excludeFilters = {@Filter( type = FilterType.CUSTOM, classes = {TypeExcludeFilter.class}), @Filter( type = FilterType.CUSTOM, classes = {AutoConfigurationExcludeFilter.class})})public @interface SpringBootApplication {

1、@SpringBootConfiguration

        本质上还是@COnfiguration,代表当前是一个配置类

2、@ComponentScan

        包扫描,指定扫描的包。可参照Spring注解驱动开发_m0_61922004的博客-CSDN博客

3. @EnableAutoConfiguration

@AutoConfigurationPackage@import({AutoConfigurationimportSelector.class})public @interface EnableAutoConfiguration {

(1)@AutoConfigurationPackage

        自动配置包

@import({Registrar.class})//给容器中导入一个组件public @interface AutoConfigurationPackage { //利用Register给容器中导入一系列组件 //将指定的一个包下的所有组件导入进来:MainApplication所在包下

(2)@import(AutoConfigurationimportSelector.class) 

1、利用getAutoConfigurationEntry(annotationmetadata);给容器中批量导入一些组件2、调用List configurations = getCandidateConfigurations(annotationmetadata, attributes)获取到所有需要导入到容器中的配置类3、利用工厂加载 Map> loadSpringFactories(@Nullable ClassLoader classLoader);得到所有的组件4、从meta-INF/spring.factories位置来加载一个文件。默认扫描当前系统里面所有meta-INF/spring.factories位置的文件 spring-boot-autoconfigure-2.3.4.RELEASE.jar包里面也有meta-INF/spring.factories

       文件里写死了springboot一启动就要给容器中加载的所有配置类:

        #Auto Configure 一共127个 

2.3.2 按需开启自动配置项

        虽然127个场景的所有自动配置启动的时候默认全部加载:xxxxAutoConfiguration,但是最终按照条件装配规则(@Conditional),会按需配置。

2.3.3 修改默认配置

        下面代码意思就是容器中没有叫规定这个名字的文件上传解析器(比如自己配置的文件上传解析器),当需要文件上传解析器组件时,springboot会找到自己配置的文件上传解析器组件,返回。

//相当于给容器中加入了文件上传解析器 @Bean@ConditionalOnBean(MultipartResolver.class) //容器中有这个类型组件@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME) //容器中没有这个名字 multipartResolver 的组件public MultipartResolver multipartResolver(MultipartResolver resolver) { //给@Bean标注的方法传入了对象参数resolver,这个参数的值就会从容器中找。 //SpringMVC multipartResolver。防止有些用户配置的文件上传解析器不符合规范// Detect if the user has created a MultipartResolver but named it incorrectlyreturn resolver;}

        SpringBoot的设计模式:SpringBoot默认会在底层配好所有的组件,但是如果用户自己配置了以用户的优先 

@Bean@ConditionalOnMissingBean//如果用户没有配,底层自动配,如果用户配了,以用户配置的为准public CharacterEncodingFilter characterEncodingFilter() { }

总结:

SpringBoot先加载所有的自动配置类 xxxxxAutoConfiguration每个自动配置类按照条件进行生效,默认都会绑定配置文件指定的值:xxxProperties。xxxProperties和配置文件进行了绑定

生效的配置类就会给容器中装配很多组件只要容器中有这些组件,相当于这些功能就有了

定制化配置

用户直接自己@Bean替换底层的组件(自己定制需要的规则,没定制的话底层自动已经配置过了)用户也可以去看这个组件是获取的配置文件什么值就去修改。

xxxAutoConfiguration ---> 组件 ---> xxProperties里面拿值 ----> application.properties

 (通过修改配置文件改变值(通过prefix找前缀),application.properties是用户自定义的配置文件)

2.3.4 最佳实践

1、引入场景依赖Developing with Spring Boothttps://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

2、查看自动配置了那些(选做)

自己分析,引入场景对应的自动配置一般都生效了配置文件application.properties中写“debug=true”开启自动配置报告,启动:Negative(不生效)Positive(生效)

3、是否需要修改

        (1)参照文档修改配置

        Common Application Properties (spring.io)https://docs.spring.io/spring-boot/docs/current/reference/html/application-properties.html#application-properties        自己分析。xxxxProperties绑定了配置文件的哪些。

        eg: 修改启动项目后控制台打印图片

        (自己去网上生成一个.txt文件 )

 

        (2)自定义加入或者替换组件

                @Bean、@Component等等

        (3)自定义器 XXXXXCustomizer;

        (4)……

2.4 开发小技巧 2.4.1 Lombok

        1、引入依赖

org.projectlombok lombok

        2、给idea安装lombok插件 

@Data//生成已有属性的getter seetter,包括toString@ToString//编译该类是自动生成toString@AllArgsConstructor//全参构造器@NoArgsConstructor//无参构造器@EqualsAndHashCode//hashcode@ConfigurationProperties(prefix = "mycar")public class Car { private String brand; private Integer price;}

================================简化日志开发===================================@Slf4j@RestControllerpublic class HelloController { @RequestMapping(value = "/hello") public String handle01(@RequestParam("name") String name){ log.info("HelloHelloHello!!!"); return "Hello, springboot 2 !"+name; }}

 

2.4.2 dev-tools

        1、引入依赖

org.springframework.boot spring-boot-devtools true

        2、项目或页面修改以后:Ctrl+F9(相当于热更新,其实是自动重启),鸡肋了感觉…… 

2.4.3 Spring Initializr(项目初始化向导)

 

 

         自动创建项目结构:

         自动生成pom.xml:

<?xml version="1.0" encoding="UTF-8"?> 4.0.0 org.springframework.boot spring-boot-starter-parent 2.6.3 com.ice.boot springboot-01-helloworld-2 0.0.1-SNAPSHOT springboot-01-helloworld-2 Demo project for Spring Boot 11 org.springframework.boot spring-boot-starter-data-redis org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 org.springframework.boot spring-boot-starter-test test org.springframework.boot spring-boot-maven-plugin

         自动生成主配置类:

package com.ice.boot.springboot;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplicationpublic class Springboot01Helloworld2Application { public static void main(String[] args) { SpringApplication.run(Springboot01Helloworld2Application.class, args); }}


核心功能 三、配置文件 3.1 文件类型 3.1.1 properties

        和以前的properties文件使用相同。

3.1.2 yaml

1、简介

        YAML 是 "YAML Ain't Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。它非常适合用来做以数据为中心的配置文件。

        yaml更注重数据本身,而不是以标记语言为主。

2、基本语法

key: value;kv之间有空格大小写敏感使用缩进表示层级关系缩进不允许使用tab,只允许空格缩进的空格数不重要,只要相同层级的元素左对齐即可'#'表示注释字符串无需加引号,如果要加,''与""表示字符串内容 会被 转义/不转义

3.  数据类型 

字面量:单个的、不可再分的值。date、boolean、string、number、null

字面量:单个的、不可再分的值。date、boolean、string、number、null

对象:键值对的集合。map、hash、set、object

行内写法: k: {k1:v1,k2:v2,k3:v3}#或k: k1: v1 k2: v2 k3: v3

数组:一组按次序排列的值。array、list、queue

行内写法: k: [v1,v2,v3]#或者k: - v1 - v2 - v3

 4、实例

@ConfigurationProperties(prefix = "person")@Component@Datapublic class Person { private String userName; private Boolean boss; private Date birth; private Integer age; private Pet pet; private String[] interests; private List animal; private Map score; private Set salarys; private Map> allPets;}

@Datapublic class Pet { private String name; private Double weight;}

# yaml表示Person对象person: #字符串也可以加引号,单引号不能识别转义字符 双引号能识别转义字符 #例如'z n t' 控制台原样输出 "z n t" 控制台换行输出 userName: 周涛 boss: true birth: 1999/03/23 20:12:33 age: 23 pet: name: Dog weight: 23.4 interests: [主持,dq] animal: - jerry - mario score: english: first: 98 second: 99 third: 99 math: [131,140,148] chinese: {first: 148,second: 136} salarys: [39999,49999.98,59999.99] allPets: sick: - {name: tom} - name: lily weight: 45 - {name: jerry,weight: 47} health: [{name: mario,weight: 47}]

@RestControllerpublic class HelloController { @Autowired Person person; @RequestMapping(value = "/person") public Person person(){ return person; }}

3.2 配置提示 

        自定义的类和配置文件绑定一般没有提示。添加依赖,使得有提示功能:

org.springframework.boot spring-boot-configuration-processor true org.springframework.boot spring-boot-maven-plugin org.springframework.boot spring-boot-configuration-processor

四、web开发 4.1 SpringMVC自动配置概览

Web (spring.io)https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.servlet.spring-mvc

         Spring Boot provides auto-configuration for Spring MVC that works well with most applications.(大多场景都无需自定义配置)

The auto-configuration adds the following features on top of Spring’s defaults:

Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.

内容协商视图解析器和BeanName视图解析器

Support for serving static resources, including support for WebJars (covered later in this document)).

静态资源(包括webjars)

Automatic registration of Converter, GenericConverter, and Formatter beans.

自动注册 Converter,GenericConverter,Formatter

Support for HttpMessageConverters (covered later in this document).

支持 HttpMessageConverters (配合内容协商理解原理)

Automatic registration of MessageCodesResolver (covered later in this document).

自动注册 MessageCodesResolver (国际化用)

Static index.html support.

静态index.html 页支持

Custom Favicon support (covered later in this document).

自定义 Favicon

Automatic use of a ConfigurableWebBindingInitializer bean (covered later in this document).

自动使用 ConfigurableWebBindingInitializer ,(DataBinder负责将请求数据绑定到JavaBean上)

If you want to keep those Spring Boot MVC customizations and make more MVC customizations (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc.

不用@EnableWebMvc注解。使用 @Configuration + WebMvcConfigurer 自定义规则

If you want to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, and still keep the Spring Boot MVC customizations, you can declare a bean of type WebMvcRegistrations and use it to provide custom instances of those components.

声明 WebMvcRegistrations 改变默认底层组件

If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc, or alternatively add your own @Configuration-annotated DelegatingWebMvcConfiguration as described in the Javadoc of @EnableWebMvc.

使用 @EnableWebMvc+@Configuration+DelegatingWebMvcConfiguration 全面接管SpringMVC 

4.2 简单功能分析

        使用Spring Initializr创建项目springboot-web-01。

 

4.2.1 静态资源访问

1、静态资源目录

        只要静态资源放在类路径下:  /static (or /public or /resources or /meta-INF/resources

   访问:当前项目根路径/ + 静态资源名

 

         如果一个控制器的请求路径也是/zt1.jpg,那么访问的就是控制器。

        因为静态资源的映射是/**。发起一次请求,先去找Controller看能不能处理,不能处理的所有请求才都交给静态资源处理器。静态资源也找不到则响应404页面。

        改变默认的静态资源路径:这样修改后,只有在根目录下的hello文件夹里的静态资源才能访问(但是访问路径上不需要加hello),其他都不能访问了(meta-INF下的resources还是能访问?????)。

 

2. 静态资源访问前缀

        为了以后拦截器拦截某些请求方便,修改默认的静态资源映射(application.yaml),改为带前缀的:

当前项目 + static-path-pattern + 静态资源名 = 在静态资源文件夹下找

3. webjar 

       WebJars - Web Libraries in Jarshttps://www.webjars.org/        添加依赖:

org.webjars jquery 3.5.1

  

        自动映射: /webjars/**

        访问地址:http://localhost:8080/webjars/jquery/3.5.1/jquery.js 后面地址要按照依赖里面的包路径:

 

4.2.2 欢迎页支持 

静态资源路径下 index.html

        · 可以配置静态资源路径

        · 但是不可以配置静态资源的访问前缀。否则导致 index.html不能被默认访问

 

        就算注释了前缀,还是404。。。springboot2.6.3 

        不要访问路径了以后,直接加一个前缀就行了!

        算了,前缀也不要了,用默认吧!前缀影响Favicon。。。

4.2.3 自定义Favicon

  

        没图标的ctrl+F5强制清理缓存! 

4.2.4 静态资源配置原理

SpringBoot启动默认加载 xxxAutoConfiguration 类(自动配置类)SpringMVC功能的自动配置类 WebMvcAutoConfiguration,看是否生效

@Configuration(proxyBeanMethods = false)@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 {}

 给容器中配了什么

@Configuration( proxyBeanMethods = false ) @import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({WebMvcProperties.class, WebProperties.class}) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {}

配置文件的相关属性和xxx(前缀)进行了绑定。WebMvcProperties==spring.mvc、WebProperties==spring.web(springboot2.6.3源码)

 1、配置类只有(只存在)一个有参构造器(源码不太明白)

//有参构造器所有参数的值都会从容器中确定 //WebPropertiesresourceProperties;获取和spring.resources绑定的所有的值的对象 //WebMvcProperties webProperties获取和spring.mvc绑定的所有的值的对象 //ListableBeanFactory beanFactory Spring的beanFactory //HttpMessageConverters 找到所有的HttpMessageConverters //ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。========= //DispatcherServletPath //ServletRegistrationBean 给应用注册Servlet、Filter.... public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider messageConvertersProvider, ObjectProvider resourceHandlerRegistrationCustomizerProvider, ObjectProvider dispatcherServletPath, ObjectProvider> servletRegistrations) { this.resourceProperties = webProperties.getResources(); this.mvcProperties = mvcProperties; this.beanFactory = beanFactory; this.messageConvertersProvider = messageConvertersProvider; this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); this.dispatcherServletPath = dispatcherServletPath; this.servletRegistrations = servletRegistrations; this.mvcProperties.checkConfiguration(); }

2. 资源处理的默认规则 

public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { this.addResourceHandler(registry, "/webjars/**", "classpath:/meta-INF/resources/webjars/"); this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (this.servletContext != null) { ServletContextResource resource = new ServletContextResource(this.servletContext, "/"); registration.addResourceLocations(new Resource[]{resource}); } }); } }

application.yaml:spring:# mvc:# static-path-pattern: "/res/**" # web:# resources:# static-locations:[classpath:/hello/] web: resources: add-mappings: false 禁用所有静态资源规则

public static class Resources { private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/meta-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"}; private String[] staticLocations;

3. 欢迎页的处理规则 

        HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。    

@Beanpublic WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),this.mvcProperties.getStaticPathPattern());welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());return welcomePageHandlerMapping;}//=====================================================================================//WelcomePageHandlerMapping构造器 WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {if (welcomePage != null && "/**".equals(staticPathPattern)) { //要用欢迎页功能,必须是/**,所以前面加前缀后404了!logger.info("Adding welcome page: " + welcomePage);setRootViewName("forward:index.html");}else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { // 调用Controller /indexlogger.info("Adding welcome page template: index");setRootViewName("index");}}

4、favicon

         /favicon

4.3 请求参数处理 4.4 数据响应与内容协商 4.5 视图解析与模块引擎 4.6 拦截器 4.7 跨域 4.8 异常处理 4.9 原生Servlet组件 4.10 嵌入式web容器 4.11 定制化原理 五、数据访问 六、单元测试 七、指标监控 八、原理解析

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。