image.png

补充:!!!还要创建WebMVC配置类:WebMVCSupport extends WebMvcConfigurationSupport

1,SpringBoot的手动创建:

A,导入SpringBoot依赖:

  1. <!-- 导入SpringBoot父起步依赖 -->
  2. <parent>
  3. <artifactId>spring-boot-starter-parent</artifactId>
  4. <groupId>org.springframework.boot</groupId>
  5. <version>2.4.5</version>
  6. </parent>
  7. <!-- 导入SpringMVC起步依赖 -->
  8. <dependencies>
  9. <dependency>
  10. <groupId>org.springframework.boot</groupId>
  11. <artifactId>spring-boot-starter-web</artifactId>
  12. </dependency>
  13. </dependencies>

B,* 创建Spring启动类:一定要启动类,否则无法启动sb程序;

//表明这是一个Spring的启动类
@SpringBootApplication
public class DemoApplication {

    //启动SpringBoot程序
    public static void main (String[] args) {
        SpringApplication.run(DemoApplication.class);
    }

}

启动SpringBoot直接启动类主函数就行了!!!

C,创建控制器:

控制器包结构:image.png

!!!注意:控制器(controller)包/类一定要放在启动类的同一级或子包中;否则会导致启动类扫描不到该包,导致无法正常执行;

//@RestController = @Controller+@ResponseBody ;
@RestController
@RequestMapping("/user")
public class UserController {

    @GetMapping("/hello")
    public String setTextHello(){
        System.out.println("hello");
        return "hello";
    }

}

* ,SpringBoot的静态资源放行:(几种方式)

A,SpringBoot中默认放行目录下的资源放行路径:

  - **/resource 目录下的 /static 路径;**
  - ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648802633972-2b8c5b75-305c-4113-8858-3e8e0641e8d5.png#clientId=uc4f0d805-0e8a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=99&id=mi7fq&margin=%5Bobject%20Object%5D&name=image.png&originHeight=99&originWidth=261&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24347&status=done&style=none&taskId=ue8205b29-d26a-4c54-b9cf-6acb03161a1&title=&width=261)
  @Override
    protected void addResourceHandlers (ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:static/");
    }
  - **/main 目录下的 /webapp 路径:(强烈不推荐)**
  - **SpringBoot本身就是一个整合框架,为何还要单独配置读取web资源文件呢?没必要**

B **,在WebMVCSupport配置类下手动配置自定义放行路径:(推荐)

虽然有默认的放行路径,但是我们一般还是要配置webMVC类的;

例:

package top.jztice5.reggie.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;

import java.util.List;


/**
 * @author Jztice5
 * @date 2022年04月04日 11:38
 */
//lombok日志输出注解
@Slf4j
@Configuration
public class WebMVCSupport extends WebMvcConfigurationSupport {

    /**
     * 设置资源管理器,设置静态资源放行,(注意:这里的管理也是由控制器进行控制)
     * 重新建立静态资源和路径的映射关系;因为所有的资源都要经过Spring框架进行处理
     *
     * @param registry
     */
    @Override
    protected void addResourceHandlers (ResourceHandlerRegistry registry) {
        //    addResourceHandler:    请求访问路径(所有 /backend/ 开头的请求都会去后面配置的“本地资源”路径下查找资源)
        //    addResourceLocations:  本地资源路径
        registry.addResourceHandler("/backend/**").addResourceLocations("classpath:/backend/");
        registry.addResourceHandler("/front/**").addResourceLocations("classpath:/front/");
    }

    /**
     * 添加(注册)消息转化器
     * @param converters
     */
    @Override
    protected void extendMessageConverters(List <HttpMessageConverter <?>> converters) {
        //1.创建消息转换器对象
        MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();

        //2. 把对象映射器交给消息的转换器
        messageConverter.setObjectMapper(new JacksonObjectMapper());

        //3. 把消息的转换器交给springmvc的消息转换器的集合中
        converters.add(0,messageConverter);
    }

}

只要是使用SpringBoot都要配置 WebMVC !!! ;继承了 WebMvcConfigurationSupport

注意:

image.png

org.springframework.boot spring-boot-starter-thymeleaf

2,SpringBoot的自动创建:

注意:自动创建缺失 WebMVC 配置;要手动进行创建;详见上;

  1. image.png
  2. image.png;
  3. image.png
  4. finish;

A,_* _SpringBoot的常用注解:

注解: 作用:
@SpringBootApplication (类注解) 它封装了核心的@SpringBootConfiguration +@EnableAutoConfiguration +@ComponentScan这三个类,大大节省了程序员配置时间,这就是SpringBoot的核心设计思想.
@EnableScheduling(类注解) 是通过@Import将Spring调度框架相关的bean定义都加载到IoC容器
@MapperScan (类注解) 支持mybatis组件的一个注解,通过此注解指定mybatis接口类的路径,即可完成对mybatis接口的扫描
@EnableAutoConfiguration 帮助SpringBoot程序将所有符合条件的@Configuration配置都加载到当前SpringBoot,并创建对应配置类的Bean,并把该Bean实体交给IoC容器进行管理
@RestController(类注解) @Controller @ResponseBody的结合,一个类被加上@RestController注解,数据接口中就不再需要添加@ResponseBody,更加简洁。
@RequestMapping 需要明确请求的路径
@GetMappping,@PostMapping, @PutMapping, @DeleteMapping 结合@RequestMapping使用, 是Rest风格的, 指定更明确的子路径.
@PathVariable 路径变量注解,用{}来定义url部分的变量名.
@Service (类注解) 这个注解用来标记业务层的组件,我们会将业务逻辑处理的类都会加上这个注解交给spring容器。事务的切面也会配置在这一层。当让 这个注解不是一定要用。有个泛指组件的注解,当我们不能确定具体作用的时候 可以用泛指组件的注解托付给spring容器(切记:在Service实现类上一定要加上这个)
@Component(类注解) 和spring的注解功能一样, 注入到IOC容器中.
@ControllerAdvice(类注解) 和 @ExceptionHandler 配合完成统一异常拦截处理.
@Mapper (类注解) 添加了@Mapper注解之后这个接口在编译时交给SpringBoot自动生成相应的代理对象;

3,* SpringBoot的配置注意:

如果导入一个starter,就相当于在父工程中导入大量的jar包,从而简化了我们在pom文件中导包的数量;
并且会在父工程进行版本的锁定,避免了在执行过程中出现依赖版本冲突;
image.pngimage.png

因此,不要顺便修改SpringBoot的版本号,避免出现版本错误,且修改版本号后会重新下载所有依赖包,浪费时间;

image.png

4,SpringBoot的基础配置:

A,三种格式:(优先级:properties最高)

image.png

注意:配置成功后,idea会在配置文件左侧显示绿叶:image.png 如果不显示的话,那到项目结构那里添加即可:image.png 配置文件已存在,添加按钮会变灰色;

B,YAML后缀的配置文件介绍:

什么是yaml,和properties有什么区别?

  • YAML(YAML Ain’t Markup Language),一种数据序列化格式;
  • yml是YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,比xml等更适合做配置文件
  • 优点:
    • 容易阅读
    • 容易与脚本语言交互
    • 以数据为核心,重数据轻格式
  • YAML文件扩展名
    • .yml(主流)
    • .yaml

image.png

  - **注意事项:**
  - ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648783340788-264a3599-c684-4e6b-913d-4841c729c9d8.png#clientId=u64f0fb6f-c314-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=342&id=ued468b1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=342&originWidth=1287&originalType=binary&ratio=1&rotation=0&showTitle=false&size=51672&status=done&style=none&taskId=uc61192e3-e0cb-485e-9aee-12389a08fa1&title=&width=1287)
  - **在多个配置属性中要使用**:**--- 来隔开上下两个属性;(常用于多环境配置)如:**![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648801780555-518cb8bf-5686-481d-9715-e4a5a4e881ff.png#clientId=uc4f0d805-0e8a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=120&id=u5ad456ef&margin=%5Bobject%20Object%5D&name=image.png&originHeight=298&originWidth=395&originalType=binary&ratio=1&rotation=0&showTitle=false&size=72173&status=done&style=none&taskId=ueacb5621-285e-410e-b673-b103963580c&title=&width=159)

!!! 注意:在yaml里面不能使用tab键,只能使用空格;

5,* yaml的数据读取:(三种方式)

  - **yml文件的数据代码:**
enterprise:
  name:aaa
  age:10
  tel:4006184000
  subject:
    - java
    - 前端

A,使用默认值 @Value:image.png

B,使用Environment对象对数据进行封装:image.png

C,自定义对象封装指定数据:(推荐)

实体类中使用@ConfigurationProperties 注解定义属性文件的数据前缀;

image.png

6,多环境开发的配置:

A,yml的配置方式:image.png

image.png

B,properties属性文件的方式:image.png

image.png

C,maven和springboot结合的方式:

  1. Maven中设置多环境属性:

image.png

  2. SpringBoot中引用Maven属性 (用properties配置文件也行):![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648816043127-9c4b5bf4-6231-47c0-bd7d-90a32ff2bd74.png#clientId=u77d8ce40-cae7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=338&id=uf69711c6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=751&originWidth=1304&originalType=binary&ratio=1&rotation=0&showTitle=false&size=94199&status=done&style=none&taskId=u2626089e-046b-4b9d-97de-bddf2d3af4c&title=&width=587)
  2. 执行Maven打包指令:![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648816056003-a0e207b5-69d9-45c9-8c8d-2cbc8bd82c09.png#clientId=u77d8ce40-cae7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=354&id=ua9134a63&margin=%5Bobject%20Object%5D&name=image.png&originHeight=354&originWidth=618&originalType=binary&ratio=1&rotation=0&showTitle=false&size=91505&status=done&style=none&taskId=u07525d5f-e3e5-483c-bd2a-13369c5ed6f&title=&width=618)![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648816066356-bded33f0-106d-4e0a-9efd-afc28eb15558.png#clientId=u77d8ce40-cae7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=225&id=u3fa49549&margin=%5Bobject%20Object%5D&name=image.png&originHeight=225&originWidth=273&originalType=binary&ratio=1&rotation=0&showTitle=false&size=30522&status=done&style=none&taskId=u0441049a-334f-4a20-a06b-3a4fbc48271&title=&width=273)
  2. 对资源文件开启对默认占位符的解析:![image.png](https://cdn.nlark.com/yuque/0/2022/png/25975946/1648816077988-b8022653-8dc0-4e52-a000-a7877119d180.png#clientId=u77d8ce40-cae7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=400&id=u32a72d55&margin=%5Bobject%20Object%5D&name=image.png&originHeight=682&originWidth=1141&originalType=binary&ratio=1&rotation=0&showTitle=false&size=59263&status=done&style=none&taskId=ufe7c751f-a30d-43ae-8e2f-4e0a94f6871&title=&width=670)

7,SpringBoot中日志的配置:

  • 在SpringBoot中默认使用的是logback处理日志;还可以使用其他日志,如Slf4j等;
  • image.png

    8,▲ SpringBoot的自动装配:

    面试题

SpringBoot自动装配流程图.drawio.pdf

6.1,SpringBoot自动装配是什么,解决了什么问题:

  - **自动装配就是为了实现从 Spring.factories 文件中获取到对应的bean对象,并且由Spring容器来帮我们进行管理;**
  - **解决了我们需要手动编写配置注入功能组件等的繁琐工作问题;**提高开发效率

6.2,* SpringBoot实现自动装配的原理:

  1. 当执行**main**方法,启动SpringBoot程序的时候,会先创建**SpringApplication类的对象**,在该对象中进行一些参数的初始化工作;最重要的就是判断当前程序的类型以及创建**初始化器Initializers**和**监听器Listener**,在这个过程中程序会调用**loadSpringFactories**方法在“**META-INF/**”目录下加载**spring.factories**文件,并将配置文件放到**缓存**中,方便后续获取;
  1. 当**SpringApplication对象**初始化完成后,开始执行run方法,来完成整个SpringBoot程序的启动;在启动过程中,最主要有两个方法,一个是**prepareContext**方法,一个是**refreshContext**方法,在这两个关键步骤中完成了自动装配的核心功能;
  1. 在**prepareContext**方法中,主要完成的是对上下文对象的初始化操作,包括了属性值的设置,比如,系统环境属性等;在整个方法执行过程中,有一个非常重要的**load**方法,该方法主要作用就是将当前启动类当做一个**beanDefinition**注册到**registry**中,方便后续在对**BeanFactoryPostProcessor**调用执行的时候,找到对应的启动类(主类),来完成对**@SpringBootApplication**,**@EnableAutoConfiguration**等注解的解析工作;
  1. 在**refreshContext**方法中,会对整个容器进行一个刷新的过程,会调用Spring中的**refresh**方法,**refresh**有13个关键方法,来完成整个Spring程序的启动,其中在**自动装配过程**中,会调用其中的**invokeBeanFactoryPostProcessor**方法,该方法主要对**ConfigurationClassPostProcessor**配置增强类进行处理,(这个类既是**BeanFactoryPostProcessor**的子类也是**BeanDefinitionRegistryPostProcessor**的子类,)在进行调用时会先调用**BeanDefinitionRegistryPostProcessor**类中的**postProcessorBeanDefinitionRegistry**方法,然后调用**postProcessorBeanFactory**方法;然后执行在里面的**postProcessorBeanDefinitionRegistry**方法的时候会解析处理各种注解,包含**@ComponentScan,@Bean,@Configuration,@Import**等在启动类上的注解,其中**最重要**的是对**@Import注解**的解析;
  1. 在解析**@Import**的时候,会有一个**getImport**方法,会从主类开始对注解进行**递归**解析,直到每一层的**@Import注解**都会被解析到,然后在**processImport**方法中对所有**Import对象**进行分类,这里主要是识别**AutoConfigurationImportSelect类对象**,并将该类归属于**ImportSelect**的子类,方便在后续过程中的调用,在**ConfigurationClassParser**类中的**getImport**方法中的**process**方法来完成对**EnableAutoConfiguration类**的加载,并根据初始化的**EnableAutoConfiguration**对象类型(导入的starter启动器及其他依赖)将放在**缓存**中的**spring.factories**文件中与其匹配的键值对(依赖包名)全部加载到SpringBoot中,再对需要的依赖或者启动器进行筛选后,根据名字加载对应的依赖并返回到(**AutoConfigurationImportSelector**)类中进行**实例化**后,放入**Spring容器**中进行管理,就实现了自动装配的整个过程;

附加 、在SpringBot项目中如何让一个Bean放到IOC容器?

1)直接在Bean上面加@Component,让该Bean的包名在项目启动类同级或子级下。
2)直接在Bean上面加@Component,在项目下写@Configuration配置类,通过@ComponentScan注解自行扫描Bean的目录
3)在项目下写@Configuration配置类(放在启动类同级或子级下),直接写一个方法创建Bean对象,方法上添加@Bean注解
4)在项目下写@Configuration配置类(不放在启动类同级或子级下),在resources/META-INF/spring.factories文件 把配置类添加到SpringBoot自动装配列表中,让其加载,在配置类中写一个方法创建Bean对象,方法上添加@Bean注解


/**
*
@
SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
*/
@SpringBootApplication
public class HelloWorldMainApplication {
public static void main(String[] args) {
// Spring应用启动起来
SpringApplication.run(HelloWorldMainApplication.class,args);
}
}

@SpringBootApplication: Spring Boot应用标注在某个类上说明这个类是SpringBoot的主配置类,运行这个类的main方法来启动SpringBoot应用;
SpringBoot启动的时候,将启动类注解中开启自动装配;

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

@SpringBootConfiguration:Spring Boot的配置类;
标注在某个类上,表示这是一个Spring Boot的配置类;
@Configuration:配置类上来标注这个注解;
配置类 ——- 配置文件;配置类也是容器中的一个组件;@Component
@EnableAutoConfiguration:开启自动配置功能;
以前我们需要配置的东西,Spring Boot帮我们自动配置;@EnableAutoConfiguration告诉SpringBoot开启自动配置功能;这样自动配置才能生效;

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

@AutoConfigurationPackage:自动配置包
@Import(AutoConfigurationPackages.Registrar.class)
Spring的底层注解@Import,给容器中导入一个组件;导入的组件由
AutoConfigurationPackages.Registrar.class;
将主配置类(@SpringBootApplication标注的类)的所在包及下面所有子包里面的所有组件扫描到Spring容器;
@Import(EnableAutoConfigurationImportSelector.class)
给容器中导入组件?
EnableAutoConfigurationImportSelector:导入哪些组件的选择器;
将所有需要导入的组件以全类名的方式返回;这些组件就会被添加到容器中;
会给容器中导入非常多的自动配置类(xxxAutoConfiguration);就是给容器中导入这个场景需要的所有组件,
并配置好这些组件;
image.png
有了自动配置类,免去了我们手动编写配置注入功能组件等的工作;
SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);
Spring Boot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值,将这些值作为自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置工作;以前我们需要自己配置的东西,自动配置类都帮我们;
J2EE的整体整合解决方案和自动配置都在spring-boot-autoconfigure-1.5.9.RELEASE.jar;