SpringBoot笔记

第一个SpringBoot程序 SpringBoot基本配置

  • 创建第一个SpringBoot程序步骤

    第一步: 创建一个Maven项目,在pom.xml中加入

       1. SpringBoot应用的父级依赖,主要的依赖其实是继承了spring-boot-dependencies
       <parent>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-parent</artifactId>
          <version>2.3.4.RELEASE</version>
       </parent>
    
          具体作用:
                spring-boot-starter-parent具体作用:
                    - pom依赖管理。  引入父pom.xml中有的依赖时无须指定版本号,自动控制匹配子依赖版本。(自动版本仲裁机制)
                    - java版本,项目编码格式,资源引用描述符已经设置好。
                    - 插件管理。
                    - 封装了配置文件的过滤规则。
                    - 封装了打可执行jar、war的配置。
                    - 封装了插件的版本信息。
                    - 封装了日期格式。
                    - 引入了eclipse和IDEA相关依赖简化了配置,达到开箱即用等。
    
    
       2. 因为创建的是一个web项目所以需要导入SpringBoot关系web项目的相关依赖集合
    
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    

    第二步: 在src--->main--->java文件夹下配置自己所需包名。

         1. 创建一个boot包,包中写SpringBoot应用的启动类(主程序类 MainApplication.class)
    
         2. 在主程序类上写@SpringBootApplication注解,告诉SpringBoot框架这是一个SpringBoot应用。
    
         3. 在主程序类中写主方法(main方法),在方法中写 SpringApplication.run(MainApplication.class,args);固定写法,启动SpringBoot。
    

    第三步: 创建Controller

         1. 在Controller包下创建Controller类,在该类上加@RestController注解,该注解 = @Controller+@RequestBody
    
         2. 在Controller类中写请求方法,返回一个字符串(HelloSpringBoot),在请求方法上写@RequestMapping注解,填写请求地址。
    

    第四步: 运行第一个SpringBoot程序

         1. 运行boot包下的主程序类(MainApplication.class).
    
         2. 在浏览器地址栏输入请求地址: http://localhost:8080/helloSpringBoot     显示: Hello SpringBoot。
    

SpringBoot配置文件 application.properties

  • application.properties 配置文件是SpringBoot的配置文件, 它可以配置Spring SpringMVC 数据库 数据源 服务器等等都可以在这里配置。

  • server.port=8888 表示修改服务器端口号。

SpringBoot打包部署 (fat jar)

  • 打包SpringBoot应用

    • 引入SpringBoot提供的打包插件

      org.springframework.bootspring-boot-maven-plugin
    • 在右侧Maven工具栏界面 Lifecycle中选中 clean 和 package 执行. 控制台显示 BUILD SUCCESS 表示打包成功

    • 在左侧项目功能栏选择本项目的target文件件--->右击---->Open in Explorer ----在弹出的文件夹里点击target
      在该文件中发现有和本项目名相同的一个 xxx.jar的包

  • 部署SpringBoot应用

    • 在控制台启动SpringBoot项目。 先在该文件夹的地址栏输出cmd,弹出命令提示符界面 ----> 输入dir命令,发现可以看到该文件---> 然后输入命令

      java -jar xxx.jar 启动该SpringBoot项目。

    • 注意:

         1. 如何查看端口号占用的进程? 如何杀死该进程?
          
              1). 根据端口查询进程命令(windows) :   netstat -ano | findstr “端口号”.
              2). 杀死pid为3036的所有进程包括其子进程(/T参数):  taskkill /T /F /PID 3036 //强制(/F参数)
      
         2. 记得关闭控制台界面的快速编辑模式(右键控制台上边框 --- > 快速编辑模式点击取消选中)
      
         3. 如果该SpringBoot项目需要jsp支持, 那么不能打成jar包,需要打成war包。
      

修改父依赖中设定的依赖版本

  • 第一步查看Spring-boot-dependencies中规定的当前依赖的版本,所使用的的key值。

  • 如果我们所需要的某个依赖版本和父依赖中设定的依赖版本不一致,需要手动在pom.xml中进行修改。

    <mysql.version>5.1.43</mysql.version>

SpringBoot starter场景启动器

  • spring-boot-starter.* * 代表了某种场景

  • 只要引入了某种starter,这个场景下的所需要用到的依赖就会自动引入。

  • 所有场景启动器的依赖,最底层的依赖都是spring-boot-starter(自动配置依赖的 核心依赖)

  • 引入场景启动器未包含的依赖,一定要写版本号。

  • 也可以创建自己定义的stater启动器

SpringBoot自动配置

  • 自动配置好了Tomcat (引入spring-boot-web 场景启动器的时候,已经自动引入Tomcat依赖),并自动配置相关功能。

  • 自动配置好了SpringMVC (引入spring-boot-web 场景启动器的时候,已经自动引入SpringMVC依赖),自动配置好了SpringMVC常用功能。

    • ConfigurableApplicationContext run= SpringApplication.run(MainApplication.class,args);
      ConfigurableApplicationContext 是一个IOC容器,包含了当前应用的所有组件。

    • 查看ConfigurableApplicationContext中包含的所有组件

        // 查看组件 (获取所有组件的名称)
        for (String beanDefinitionName : run.getBeanDefinitionNames()) {
        System.out.println(beanDefinitionName);
        }
      
    • 组件中包含 DisPatcherServlet、CharacterEncodingFilter、视图解析器、文件上传解析器等等

  • 默认包结构

    • 自动扫描包,只要是主程序包同级包或者主程序包下的子包孙子包都会被自动扫描,不用再手动配置包扫描。

    • 如果有程序必须放在自动扫描包之外的话,也可以手动配置需要扫描的包。在主程序上的@SpringBootApplication注解属性中写需要扫描的包.
      @SpringBootApplication (scanBasePackages = "com.shi")。 或者 使用@ComponentScan注解 指定扫描路径。

  • 各种配置项都有默认值

    • 这些默认配置最终都是映射到某一个类之上的,这个类会在容器里创建对象。

    • application.properties 配置文件中可以修改各项配置的默认值。

  • 按需加载配置项

    • SpringBoot有很多场景启动器(starter),这些场景不会都自动开启配置。

    • 我们引入了哪些场景,哪些场景的自动配置才会开启。

    • 所有的自动配置项都在 spring-boot-autoconfigure 中

向容器中注册组件

  1. 在boot文件夹下边添加一个config包,在config包中写一个MyConfig配置类。

  2. 在该类的上边写@Configuration注解, @Configuration注解的作用: 告诉SpringBoot这是一个配置类 == 等同于配置文件。

  3. 将所需实体类注册在容器中。在MyConfig类中写注册方法, 方法返回值为所注册的类的类名 然后自定义方法名,返回一个该类的对象。

  4. 在该方法的上边写@Bean注解,相等于 方法名相当于, 方法的返回值类型就是所需要的对象,return的返回值就是容器中保存的对象实例。

  5. 也可以自定义组件名称,@Bean("自定义的名字")

  6. 该方式获取的组件是默认是单实例的,获取的所有都是同一个对象。

  7. 配置类本身也是一个组件。

  8. 无论外界对配置类中的这个组件注册方法调用多少次获取的都是之前注册进容器中的单实例bean。

  9. @Bean标注的方法如果有对象类型的形式参数,那么就会自动到容器中去找这个对象,使用在容器中找到的相同类型的对象,给形参自动赋值。

  10. SpringBoot新特性: @Configuration(proxyBeanMethods = true)该属性默认为true。

    • proxyBeanMethods, 该属性默认为true代表着代理对象去调用方法获取对象,那么SpringBoot默认就会检查容器中是否存在该对象,
      如果容器中有就取出来,如果没有再来调用创建该实例对象。归根结底是为了保持组件的单实例。
      User user1 = run.getBean(MyConfig.class).getUser();
      User user2 = run.getBean(MyConfig.class).getUser();
      user1 = user2

    • proxyBeanMethods, 如果将该属性显性的定义为false,那么获取两个对象,这两个对象将不是同一个对象,不相等。
      User user1 = run.getBean(MyConfig.class).getUser();
      User user2 = run.getBean(MyConfig.class).getUser();
      user1 != user2

  11. proxyBeanMethods = true 就是Lite模式
    proxyBeanMethods = false 就是Full模式

  12. 例子: 配置类

  @Configuration
  public class MyConfig {
      @Bean
      public User getUser(){
        return new User("张三",20);
      }

      @Bean
      public Pet getPet(){
        return new Pet("TomCat");
      }

}

@Import注解

  • @Import注解用来实现把实例加入spring的IOC容器中, 该注解要放在能被扫描到的类的上边。

  • @Import注解的使用: @Import({User.class, Pet.class}) 该注解中可以放多个类,放入的类会自动注册到IOC容器中,容器会创建相应的对象实例。

@Conditional注解 条件装配

  • @Conditional注解, 当满足了@Conditional注解规定的某种条件,则进行组件注入。

  • @Conditional注解下有很多派生注解。例如:

    • @ConditionalOnBean注解, 是指当容器中存在我们指定的bean的时候,我们才做某一件事。

    • @ConditionalOnMissingBean注解, 是指当容器中没有某一个Bean的时候,我们才做某一件事情。

    • @ConditionalOnClass注解, 是指当容器中存在我们指定的Class的时候,我们才做某一件事。

    • @ConditionalOnMissingClass注解, 是指当容器中不存在某一个Class的时候,我们才做某一件事。

  • 实例演示

    • @ConditionalOnBean(name = "getPet") 写在类上的时候是指: 当容器中存在beanName为 "getPet" 的bean的时候,下面的所有注册bean方法才生效

    • @ConditionalOnBean(name = "getPet") 写在某个方法上的时候是指: 当容器中存在beanName为 "getPet" 的bean的时候,该注册当前bean的方法才生效。

    • 注意: bean注册方法是按顺序加载的,前后的方法注册的条件是后面的方法的话,会一直不满足条件。

  • 全部派生注解

        @ConditionalOnJava	              系统的java版本是否符合要求
    
        @ConditionalOnBean	              容器中存在指定Bean;
    
        @ConditionalOnMissingBean	      容器中不存在指定Bean;
    
        @ConditionalOnExpression	      满足SpEL表达式指定
    
        @ConditionalOnClass	          系统中有指定的类
    
        @ConditionalOnMissingClass	      系统中没有指定的类
    
        @ConditionalOnSingleCandidate	  容器中只有一个指定的Bean,或者这个Bean是首选Bean(首选实例(主实例)被@Primary注解标注的bean)
    
        @ConditionalOnProperty	          系统中指定的属性是否有指定的值(配置了某个属性的值)
    
        @ConditionalOnResource	          类路径下是否存在指定资源文件
    
        @ConditionalOnWebApplication	  当前是web环境
    
        @ConditionalOnNotWebApplication  当前不是web环境
    
        @ConditionalOnJndi	              JNDI存在指定项
    

@ImportResource注解

  • 该注解用于将使用bean.xml中使用标签配置的bean,在bean配置类中通过引入beans.xml文件,将配置文件中的bean转换成使用java配置类配置的bean。

  • 例如在MyConfig类上使用 @ImportResource("classpath:beans.xml"), 导入了beans.xml文件,就会自动转换成java配置类配置的bean了。

@ConfigurationProperties注解 进行配置绑定

  • @ConfigurationProperties 配置绑定. 有时候需要为实体类中的属性赋值,我们可以在properties中配置属性的值, 然后将实体类和properties配置文件
    绑定起来, @ConfigurationProperties就是将二者进行绑定。

  • @ConfigurationProperties 配置绑定.写在实体类上。

  • @ConfigurationProperties("mycar"), 通过指定的前缀(该前缀就是properties配置文件中写的属性名,这里的mycar),绑定配置文件中属性名为(mycar的属性),
    然后自动将properties中的属性值,赋给实体类的属性。

  • 该注解可以放在类上,写在类上的时候,该类要先加@Component注解,将该类交给容器托管; 也可以写在方法上, 当将该注解作用于方法上时,如果想要有效的绑定配置,
    那么该方法需要有@Bean注解且所属Class需要有@Configuration注解。

@EnableConfigurationProperties注解

  • 该注解和@ConfigurationProperties注解是配合使用的,如果@ConfigurationProperties注解所标注的实体类,
    没有先使用@Component注解将该实体类注册到容器中,那么直接使用@ConfigurationProperties注解是无效的,所以在不使用@Component注解的情况下,
    可以在配置类中(MyConfig),类上使用@EnableConfigurationProperties注解,先声明一下使用@ConfigurationProperties注解所标注的实体类,
    这样就可以正常使用 @ConfigurationProperties注解了。

  • @EnableConfigurationProperties(Car.class),表示开启Car这个类的属性配置绑定功能,并将Car这个组件自动注入到容器中。

  • 注意@EnableConfigurationProperties注解必须写在配置类上。

主程序类注解 @SpringBootApplication注解分析

  • @SpringBootApplication注解包括:

        @Target({ElementType.TYPE})
        @Retention(RetentionPolicy.RUNTIME)
        @Documented
        @Inherited
        @SpringBootConfiguration
        @EnableAutoConfiguration
        @ComponentScan
    
  • 分析第一个子注解 @SpringBootConfiguration

    • 该注解下又包括一个@Configuration,代表该类是一个配置类。
  • 分析第二个子注解 @EnableAutoConfiguration

    • @AutoConfigurationPackage 自动配置包,指定了包规则。
      该注解下又包含一个@Import({Registrar.class}) 利用Registrar给容器中批量注册组件,Register获取到了包名。(也就是注册某一个包下的所有组件)
      这个包就是MainApplication所在的包。

    • @Import({AutoConfigurationImportSelector.class})

      1.利用AutoConfigurationImportSelector类的getAutoConfigurationEntry(annotationMetadata)方法,给容器导入一些组件。

      2.利用 List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes)
      获取所有候选的需要导入到容器中的配置类。

      3.利用工厂加载器Map<String, List> loadSpringFactories(@Nullable ClassLoader classLoader)会得到所有的组件
      从MATE-INF/spring.factories位置来加载一个文件,默认扫描当前系统MATE-INF/spring.factories位置的所有文件,文件中写死了
      SpringBoot启动时需要加载的所有配置类。

      4.虽然127个场景在SpringBoot开启的时候默认全部加载,但是最终会按着条件装配规则(@Conditional注解),进行按需配置。

      5.SpringBoot底层会配置好所有的组件,如果用户配置了,优先用户配置。

      6.定制化配置
      - 用户使用@Bean替换底层的组件
      - 用户去看这个组件是获取的配置文件的哪个属性的值,去配置文件进行修改

      7.xxxAutoConfiguration ---> 创建很多组件 ---> 组件从xxxProperties中取值 --->xxxProperties从配置文件中获取值。

  • 分析第三个子注解 @ComponentScan 这是一个包扫描注解,指定需要扫描的包。

  • 怎么修改配置文件? 怎么准确的找到所要修改的某一个组件的某一个属性?

    • External Libraries --- > spring-boot-autoconfigure-2.3.4.RELEASE.jar ---> org ---> springframework ---> boot ---> autoconfigure

    • 该路径下是所有的组件,想要配置哪个组件的属性,就点开哪个组件的文件夹。

    • 每一个组件的第一个都是XXXAutoConfiguration(这里是CacheAutoConfiguration.class ),
      点开该类可以看到该注解, @EnableConfigurationProperties({CacheProperties.class}),可以看到该组件是和CacheProperties进行了绑定。
      点开CacheProperties.class,可以看到@ConfigurationProperties(prefix = "spring.cache") 配置绑定注解,设定的配置文件前缀是"spring.cache"。
      所以和CacheAutoConfiguration相关的属性值就是以 "spring.cache" 为开头进行配置。
      可以在application.properties中进行配置,例如: spring.cache.cache-names=myCache。

创建一个SpringBoot项目总结

  1. 引入正确的场景依赖

    场景依赖:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.build-systems.starters

  2. 查看哪些自动配置类生效了,哪些没有生效

    • 在application.properties中,写 debug=true,就可以看自动配置报告。 当项目启动的时候会在控制台打印哪些生效了,哪些没生效。

    • (Negative matches / Did not match 表示没有生效) (Positive matches 表示已生效)

  3. 是否需要修改某些配置项的属性值

SpringBoot Developing Tools (实现热更新 自动重启)

  • 官网文档:https://docs.spring.io/spring-boot/docs/current/reference/html/using.html#using.devtools

  • 在pom.xml文件中添加 spring-boot-devtools依赖。

    org.springframework.bootspring-boot-devtoolstrue
  • 其主要作用是热更新(自动重启), 添加了该依赖以后,对项目做修改后不用重新启动项目查看, 只需要修改以后 "CTRL+F9" 即可完成更新

  • 包括修改静态页面、请求路径、返回值、配置文件等等。

  • Jrebel 一种付费实现热更新的方法 它不是重启,而是重新加载。在插件中下载。

Spring Initailizr(项目初始化向导)

  • Spring Initailizr 快速创建所需场景的SpringBoot应用。

YAML "YAML Ain't a Markup Language"

  • 什么是YAML?

    YAML 是 "YAML Ain't a Markup Language"(YAML 不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。

    YAML 的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。

    YAML 的配置文件后缀为 .yml,如:runoob.yml 。

  • YAML的基本语法?

    • key: value k:空格v KV之间有空格。
    • 大小写敏感
    • 使用缩进表示层级关系
    • 缩进不允许使用tab,只允许空格
    • 缩进的空格数不重要,只要相同层级的元素左对齐即可
    • '#'表示注释
    • 适合配置数据,而不是行为动作。
    • 扩展名可以使 .yaml 或者 .yml
    • 在一个字符串中加入 /n ,并且把该字符串用 单引号 引起来, /n会和字符串一起输出为/n,没有转义的作用;而如果将该字符串用双引号引起啦/n会识别为转义字符,实现换行功能。
  • 在xxx.yml配置文件中写自定义类的属性的时候,发现没有提示功能,如何使自定义类也有提示功能呢?

    • 需要创建配置处理器

    • 如何创建配置处理器呢?

      1. 将配置处理器所需依赖加入到pom.xml中

        org.springframework.bootspring-boot-configuration-processortrue
  • 配置文件的加载顺序

    application.properties > application.yml > application.yaml

如何读取配置文件的内容

  • 读取配置文件过程中的问题 出现"expected , but found BlockMappingStart"
    解决: 配置文件中的父级属性顶行写,不要有空格。

  • 读取配置文件中属性值的三种方式

    1. @Value

      @Value用法:

      • @value获取单一一个属性值
        @Value("${call}")
        private String name;
        适用于获取某一个属性的值,要保证大括号中的属性名和yaml中的属性名保持一致。这样就可以把call的值赋值给name了。

      • @Value获取一个对象的属性值,需要分别获取对象中的每个属性的值。

        @Value("${Person.name}")
        private String isName;

        @Value("${Person.age}")
        private Integer age;

      • @Value获取配置文件中数组的值,需要按照数组下标依次获取.

        //通过@Value获取yaml中数组的值
        @Value("${address[0]}")
        private String cityName1;

        @Value("${address[1]}")
        private String cityName2;

        @Value("${address[2]}")
        private String cityName3;

    2. Environment对象

      用法:
      - 第一步 创建Environment对象
      @Autowired
      private Environment environment;

      - 第二步: 通过方法获取属性值
              String name = environment.getProperty("Person.name");
              String age = environment.getProperty("Person.age");
              String address1 = environment.getProperty("address[0]");
      
    3. @ConfigurationProperties 配置绑定 将实体类和配置文件进行绑定

    用法:

    第一步: 给实体类加上  @Component注解, 将该类注册为容器中的组件。
    第二步: 给实体类加上  @ConfigurationProperties(prefix = "person")注解  绑定配置文件,代表该实体类的父级属性前缀为person。
    第三步: 在Controller类中 创建实体类对象并添加 @Autowired注解,实现自动装配。
    第四步: 在配置文件中添加属性值。例如:person.name: SHIGE
    

    注意: 实体类的属性名 需要和配置文件中的属性名保持一致

    扩展1: 在pom.xml中添加配置处理器依赖,添加该依赖以后,在配置文件中配置属性值的时候会有提示信息。(添加完以后需要reBuild一下)

    <!--配置处理器 实现配置文件提示-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    

    扩展2: @EnableConfigurationProperties注解

        - 该注解和@ConfigurationProperties注解是配合使用的,如果@ConfigurationProperties注解所标注的实体类,没有先使用
          @Component注解将该实体类注册到容器中,那么直接使用@ConfigurationProperties注解是无效的,所以在不使用
          @Component注解的情况下,想要使用@ConfigurationProperties注解,进行配置绑定,应该怎么办呢?
          
          第一步: 在config包下创建一个配置类(MyCofnig),然后使用配置类的方式注册实体类Bean。
          第二步: 在配置类(MyConfig)类上使用@EnableConfigurationProperties注解,代表声明了该配置类所注册的bean
                 可以与@ConfigurationProperties注解所标注的实体类进行绑定,这样就可以正常使用 @ConfigurationProperties注解了。
        
        - 用法:  @EnableConfigurationProperties(Car.class),表示开启Car这个类的属性配置绑定功能,并将Car这个组件自动注入到容器中。
        
        - 注意@EnableConfigurationProperties注解必须写在配置类上。
    

SpringBoot Web开发

静态资源目录(访问静态资源)

  • 类路径下: /static、 /public、 /resources、 /META-INF/resources 这些目录都可以作为静态资源目录,静态资源放在这些目录下都可以自动被识别到。

  • 访问路径: 当前项目的根路径/静态资源名。 http://localhost:8080/banner.jpg

  • 框架是如何识别出是一个请求还是一个静态资源的呢?

    • 测试 在Controller中写一个请求,请求路径名和资源名一致,都为"banner.jpg".
      测试发现框架会识别为一个请求路径,输出了controller中返回的字符串,并没有显示静态资源图片。
      请求一进来,会先识别为一个Controller,先去看Controller能不能处理,如果能处理,直接交给Controller处理,如果Controller不能处理,
      那么就将Controller、不能处理的所有请求交给静态资源器处理,就回去指定的静态资源目录搜索能处理的静态资源。如果静态资源中可以找到,那么就会处理了,
      如果静态资源也找不到的话,就会报错404.
  • 默认情况下,项目根路径+资源名就能访问静态资源(请求路径中不必有静态资源文件夹名 http://localhost:8080/banner.jpg),
    如果想要在请求路径中给静态资源加一个前缀(请求路径中有静态资源文件夹名),怎么做呢? (给静态资源加前缀是为了后面拦截器的配置)

    • 在application.yaml配置文件中配置该前缀。
      spring:
      mvc:
      static-path-pattern: /res/**
    - 写了这个配置以后访问静态资源就需要加上配置的前缀,这样框架会在去静态资源文件夹下寻找该静态资源。
      http://localhost:8080/res/m.jpg
    
  • 如何自定义静态资源文件夹?

       自定义静态资源文件夹:
           resources:
           static-locations: [classpath:/haha/]  代表以后haha文件夹才是我的静态资源文件夹.
    

WebJars 的应用

  • 网址: https://www.webjars.org/

  • 什么是webjars?

    • WebJars是将客户端(浏览器)资源(JavaScript,Css等)打成jar包文件,以对资源进行统一依赖管理。WebJars的jar包部署在Maven中央仓库上。

    • webjars中有css、jQuery、Bootstrap等静态资源的Maven依赖,可以将这些依赖,引入到pom.xml中。就相当于导入了这些静态文件。

      org.webjars
      jquery
      3.6.0

    • 访问Maven自动导入webjars的js文件 : http://localhost:8080/webjars/jquery/3.6.0/jquery.js
      要按照maven导入的包路径访问。

欢迎页面的设置

  • SpringBoot配置欢迎页面有两种方式:

    • 第一种静态方式: 将index.html放在静态资源文件夹中,就会自动被当做欢迎页。(前提是没有配置静态资源访问前缀)

    • 第二种方式: 在Controller下写一个处理"/"请求的方法。

                  @RequestMapping(value = "/")
                  public String index(){
                           return "forward:login.html";
                  }
      
  • favicon.ioc 网站图标设置

    • 将网站图标文件命名为favicon.ioc 然后将该文件放在静态资源文件夹中,会自动识别为网站图标。

静态资源配置原理

  • SpringBoot启动后会默认加载很多xxxAutoConfiguration自动配置类(自动配置类)。

  • SpringMVC的自动配置类为 WebMvcAutoConfiguration。

  • 看WebMvcAutoConfiguration给容器中配置了什么?

Rest 与 请求映射

  • 什么是Rest?

    • REST即表述性状态传递(英文:Representational State Transfer,简称REST)是一种软件架构风格。
      它是一种针对网络应用的设计和开发方式,可以降低开发的复杂性,提高系统的可伸缩性。

    • 具体使用: 将RequestMapping中的所有的请求路径名写成一样的,然后将method属性的请求方式,设置为相应的请求方式(前后端保持一致),
      这样就可以通过请求方式来识别请求。

    • 使用Rest需要先在配置文件中开启支持Rest风格。

      开启rest
       spring:
         mvc:
           hiddenmethod:
            filter:
                enabled: true
      
    • 前端form标签的 method属性默认只能写两种请求方式,post和get。怎么才能写delete请求 和 put请求呢?

      首先将 请求方式写为Post,然后需要在form在添加一个标签

      1.Put请求

      2.Delete请求

  • Rest原理(基本表单提交)

    • 首先表单提交的时候会带上 _method参数(method=Put)。

    • 请求过来以后HiddenHttpMethodFilter拦截到,HiddenHttpMethodFilter会先判断该请求是不是post请求
      然后获取到_method属性的值,判断_method属性的值是否在DELETE PUT PATCH三者范围内
      如何在范围内就给Request请求方式重新赋值为_method属性的值。

  • 请求注解
    @GetMapping = @RequestMapping(value = "/user",method = RequestMethod.GET)
    @PostMapping = @RequestMapping(value = "/user",method = RequestMethod.POST)
    @DeleteMapping = @RequestMapping(value = "/user",method = RequestMethod.Delete)
    @PutMapping = @RequestMapping(value = "/user",method = RequestMethod.PUT)

  • 如何把input标签中hidden属性的值"_method",配置为我们自定义的名字?

    • 创建一个配置类

      @Configuration(proxyBeanMethods = false)
      public class WebConfig {
      //修改input标签中hidden属性的值"_method",配置为我们自定义的名字。
      @Bean
      public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
      HiddenHttpMethodFilter hiddenHttpMethodFilter = new HiddenHttpMethodFilter();
      hiddenHttpMethodFilter.setMethodParam("myMethod");
      return hiddenHttpMethodFilter;

         }
      

      }

请求映射

  • 请求进来会先调用HttpServlet的doGet()方法,然后doGet()方法中会调用FrameWorkServlet类中的processRequest()方法,processRequest()方法
    会调用同类中的doService()方法,然后doService()方法会调用DispatcherServlet类中的doDispatcher()方法。

  • 所以SprigMVC的DispatcherServlet的核心方法是doDispatch()方法,

  • 那么DispatcherServlet的核心方法doDispatch()方法,是怎么确定哪个请求适合用哪个Controller中的哪个方法进行处理的呢?

    1.HandlerMapping 处理器映射器 该对象中封装了 Map("请求路径","Controller")

    - 该对象下有五组HandlerMapping,包括框架自带的和我们创建的
    
       RequestMappingHandlerMapping   中有个MappingRegistry中保存了所有@RequetsMapping和Handler的映射规则(哪个请求路径对应哪个Controller下的哪个方法)
       WelcomePageHandlerMapping      欢迎页面的HandlerMapping
       BeanNameUrlHandlerMapping
       RouterFunctionHandlerMapping
       SimpleUrlHandlerMapping
    
    - 请求到了doDispatch()方法中会遍历HandlerMapping中的五组HandlerMapping,遍历所有映射信息,根据接收到的请求路径找到路径对应的Handler。
    

常用参数注解使用

  • @PathVariablea注解,获取路径变量的值。

  • @RequestHeader注解,获取请求头。

    - 获取某个请求头参数   @RequestHeader("User-Agent") String userAgent
    
    - 获取所有请求头参数   @RequestHeader Map<String,String> herders
    
  • @RequestParam 获取请求参数

    - 获取某个请求参数            @RequestParam("interest") String hobby
    
    - 获取所有请求参数的Map集合    @RequestParam Map<String,String> params 
    
  • @CookieValue 获取Cookie的值

    - 获取Cookie的值        @CookieValue("cookie id") String Idea-133f6e8b
    
    - 获取Cookie的所有信息   @CookieValue("Cookie ID") Cookie cookie
    
  • 获取请求体中的数据

    - @RequestBody String content
    
  • 获取请求域(request域)中的参数

    - @RequestAttribute("username") String username, @RequestAttribute("code")Integer code
    
  • @MatrixVariable() 矩阵变量

    • 语法: /cars/sell; low=34; brand=byd,audi,yd 每个属性之间用分号分割,每个属性值之间用逗号分割。
      http://localhost:8080/cars/sell;low=34;brand=byd,audi,yd

    • SpringBoot默认禁止使用矩阵变量。

    • 手动开启SpringBoot矩阵变量支持

      原理: 对于所有请求路径的处理都是使用UrlPathHelper进行解析的,UrlPathHelper中有一个属性removeSemicolonContent。
      removeSemicolonContent属性是来支持矩阵变量的,该属性等于true意思是 移除分号后的内存,false代表不移除。

      方式一: 配置类 实现WebMvcConfigurer 重写configurePathMatch方法

      public void configurePathMatch(PathMatchConfigurer configurer){
          UrlPathHelper urlPathHelper = new UrlPathHelper();
      
           //不移除分号后边的内容 这样举证变量才可以生效
            urlPathHelper.setRemoveSemicolonContent(false);
            configurer.setUrlPathHelper(urlPathHelper);
      }
      

      方式二: 配置类不做实现, 利用@Bean方式实现

      @Bean
       public WebMvcConfigurer webMvcConfigurer(){
       return new WebMvcConfigurer() {
              @Override
              public void configurePathMatch(PathMatchConfigurer configurer) {
                       UrlPathHelper urlPathHelper = new UrlPathHelper();
      
                       //不移除分号后边的内容 这样举证变量才可以生效
                       urlPathHelper.setRemoveSemicolonContent(false);
                       configurer.setUrlPathHelper(urlPathHelper);
               }
           };
       }
      

各种注解参数的获取解析处理原理

  • HandlerMapping 处理器映射器 该对象中封装了 Map("请求路径","Controller")。

  • 从HandlerMapping中找到能处理相应请求的Handler(Controller.method())。

  • 然后为当前Handler找到一个能处理当前请求的适配器HandlerAdapter,该适配器下有四种不同的处理器适配器。

       RequestMappingHandlerAdapter    用来处理标注了@RequestMapping
       HandlerFunctionAdapter          用来支持函数式编程
       HttpRequestHandlerAdapter
       SimpleControllerApapter
    

参数绑定

  • 数据绑定: 页面提交的数据无论是get还是post请求都可以和对象的属性进行自动绑定。

        前端页面所提交数据的name属性和实体类中的对象属性保持一致,后台Controller中直接返回一个该类型的对象,会发现数据直接自动封装好了。
    
  • 如何实现属性自动一一绑定的呢?

    WebDataBinder :Web数据绑定器,将请求的参数值绑定到指定的javaBean中。
    WebDataBinder利用它里面的Converters将请求中的数据类型转换为指定的数据类型,再次封装到javaBean中。

    GenericConversionService: 在设置每一个值的时候,遍历GenericConversionService里面所有的Converter,找到那个可以将request带来的参数
    转换为指定的类型的Converter。

  • 可以通过自定义Converter,来封装数据

    • 可以在WebConfig类中,重写addFormatters,自定义属性绑定规则
      //重写addFormatters
      public void addFormatters(FormatterRegistry registry){
      registry.addConverter(new Converter<String, Addr>() {
      @Override
      public Addr convert(String source) {
      //地址,邮编
      if(!StringUtils.isEmpty(source)){
      Addr addr = new Addr();
      String[] splitStr = source.split(",");
      addr.setAddr(splitStr[0]);
      addr.setZip(Integer.parseInt(splitStr[1]));
      return addr;
      }
      return null;
      }
      });

响应数据(ReturnValueHandler)

  • 响应JSON(jackson+ResponseBody)

    • 第一步引入web场景

      org.springframework.bootspring-boot-starter-web

      web场景中又包含(自动引入)json场景

      org.springframework.boot
      spring-boot-starter-json
      2.3.4.RELEASE
      compile

    • 第二步创建一个Controller 在该类上或者类下的某个方法上加上@ResponseBody注解,会给前端自动返回json字符串。

  • 是怎么做到自动返回json数据的呢?

    • returnValueHandler(返回值处理器)

      Controller返回一个数据给返回值处理器,返回值处理器会先使用boolean SupportReturnType()方法 去判断是否支持该种类型的返回值,(15种)
      如果支持那么就调用HandlerReturnValue()返回值处理器中的selectHandler()方法,遍历出一个可以处理当前返回值类型的方法,然后调用该方法进行处理。

  • SpringMVC支持哪些返回值?

    • ModelAndView
    • Model
    • View
    • ResponseEntity
    • ResponseBodyEmitter
    • StreamingResponseBody
    • HttpEntity
    • HttpHeaders
    • Callable
    • DeferredResult
    • listenableFuture
    • CompletionStage
    • WebAsyncTask
    • 返回值有标注 @ModelAttribute注解
    • 返回值标注有: @ResponseBody注解 ---> 会使用RequestResponseBodyMethodProcessor返回值处理器进行处理
  • RequestResponseBodyMethodProcessor返回值处理器 可以处理标注了@ResponseBody的返回值,它又是怎么工作的呢?

    • 利用MessageConverters()进行处理
      1.判断我们的值是否是字符串类型
      2.内容协商: 浏览器会在请求头中告诉服务器,浏览器所能接受的内容格式
      3.服务器根据自身的实际情况,决定服务器能产出什么类型的数据
      4.HttpMessageConverter(xxx.Class,MediaType) 判断该Class是否能能够转换为MediaType。

视图解析与模板引擎

  • SpringBoot 默认打包方式是一个jar包, jar包是一个压缩包,jsp不支持在压缩包内编译的方式,所以SpringBoot默认不支持JSP,需要引入第三方模板引擎
    进行页面渲染

  • SpringBoot中的模板引擎有: freemarker、 groovy-templates、thymeleaf。

  • thymeleaf是一个服务端的java模板引擎

    表达式名字 语法 用途

    变量取值 ${...} 获取请求域、session域、对象等值

    选择变量 *{...} 获取上下文对象值

    消息 #{...} 获取国际化等值

    链接 @{...} 生成链接

  • 使用 thymeleaf

    • 第一步在pom.xml中 引入 thymeleaf 的stater
      引入后框架自动配置好了默认前缀classpath:templates 后缀: .html

    • 第二步在templates文件夹中新建一个html ,然后在这个HTML中声明 thymeleaf ,引入命名空间

Spring缺点

  • 缺点: 配置繁琐(XML) 依赖繁琐(依赖版本冲突等等)

SpringBoot的优点

  • 自动配置、 起步依赖、 辅助功能(嵌入式服务器、安全、健康 指标检测、外部配置等)、 解决了Spring的痛点。

  • SpringBoot提供了一种快速使用Spring的方式,而不是对Spring功能上的增强。

SpringBoot小结

  • SpringBoot在创建项目的时候使用jar的打包方式。

Profile

  • 在开发SpringBoot应用时,通常一套程序会被安装到不同的环境中,比如开发环境、测试环境、生产环境等,其中每一套环境的数据库地址,服务器端口等配置
    都是不同的,如果每次打包的时候都需要修改配置文件,那么就会非常麻烦。Profile 的功能就是进行动态配置切换的。

  • 通俗讲 就是指可以写多套配置属性分别服务 开发、 测试、 生产、 做哪个操作就切换到哪套配置中。

  • profile的配置、

    • 第一种配置方式 多配置文件方式

             第一步: 在resources下创建三个配置文件(properties/yaml),分为命名为:如下。
                    三个配置文件分别代表了开发环境的配置文件,测试环境的配置文件,和生产环境的配置文件。
                                        application-dev.properties
                                        application-pro.properties
                                        application-test.properties
            
             第二步: 激活配置文件(不激活的话这些配置文件无效)
            
                    - 在 application.properties主配置文件中进行激活操作。
           
                    - 代码: spring.profiles.active=dev (子配置文件的文件名中 - 后边的字符代表了该配置文件) 
      
    • 第二种配置方式: yaml多文档配置方式

      第一步: 一个application.yml文件可以分割成多个不同的部分。使用符号" --- " 进行分割。

      第二步: 给分隔的每一部分起一个名字:
      spring:
      config:
      activate:
      on-profile: test/dev/pro

      第三步: 激活某一部分的配置(不激活是无效的)
      spring:
      profiles:
      active: dev/test/pro # 代表激活名称为dev部分的配置

          - 这里的配置也可以不修改配置文件,可以在图形化界面进行编辑虚拟机参数。
      
            run --->Edit Configurations---->Confifuration---->Environment---->VM options  -Dspring.profiles.active=pro
                    
            或者:   run --->Edit Configurations---->Confifuration---->Environment---->VM options  --spring.profiles.active=pro
      
          - 打包运行 黑马第11节课
      

SpringBoot 配置文件的加载顺序 对应项目 springboot-04-profile

  • SpringBoot启动的时候会在当前项目的以下目录下加载配置文件: /config 、 当前项目的根目录、 classpath/config目录 、classPath的根目录、
    加载顺序为书写顺序,高优先级的配置文件会覆盖低优先级的配置文件。

  • 高优先级的配置文件只会覆盖低优先级配置文件中相同的属性值,而如果高优先级配置文件中没有配置的属性,在低优先级配置文件中配置了该属性,那么还是会加载低优先级的属性。

  • 读取外部配置文件, 可以在项目之外写一个文件, 然后以命令行的方式指定该配置文件的路径 spring.config.location = 路径

  • 也可以将外部配置文件放在和.jar包的同级目录中,这样项目加载的时候会自动读取该配置文件

  • 会先加载外部配置文件,再加载内部配置文件

SpringBoot 整合Junit

  • 第一步搭建SpringBoot工程

  • 引入spring-boot-start-test依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    
  • 编写测试类
    Maven项目已经写好测试包直接写测试类就可以了

  • 添加测试相关注解

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = Springboot05JunitApplication.class) //此处填写 主类.Class
    public class UserServiceTest {
       @Resource
       private UserService userService;
    
       @Test
       public void test(){
            userService.add();
       }
    }
    
  • 编写测试方法

     @Test
     public void test(){
           userService.add();
     }
    

SpringBoot整合Redis

  • 搭建SpringBoot工程

  • 引入Redis依赖

    org.springframework.bootspring-boot-starter-data-redis
  • 配置Redis相关属性
    在application.yml中进行配置
    spring:
    redis:
    host: 127.0.0.1 #redis的主机IP
    port: 6379

  • 注入RedisTemplate模板
    @Resource
    private RedisTemplate redisTemplate;

  • 编写测试方法进行测试
    @Test
    public void testSet() {
    //添加数据
    redisTemplate.boundValueOps("name").set("张三");
    }

@Test
public void testGet() {
//取出数据
Object name = redisTemplate.boundValueOps("name").get();
System.out.println(name);
}

SpringBoot整合JDBC

  • 搭建SpringBoot工程

  • 导入JDBC依赖,MySql驱动、

     - 该依赖中包括:  数据源、jdbc、spring tx 事务
     <!--JDBC-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-jdbc</artifactId>
     </dependency>
    
     - 驱动的版本要和本机的MySql版本一致
     <!--MySql驱动-->
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <!--<scope>runtime</scope>-->
     </dependency>
    

配置Druid数据源

第一种方式: 手动配置

  • 引入Druid依赖

    com.alibaba
    druid
    1.1.8

  • 在config类中配置druid
    在: springboot-07-mybatis config

  • 配置druid监控页
    在: springboot-07-mybatis config

  • 测试
    创建 Datasource 实例 ,添加自动注入@Autowired

第二种方式 引入 druid-starter

  • 第一步 引入 druid-starter

    com.alibaba
    druid-spring-boot-starter
    1.2.6

SpringBoot 整合Mybatis

  • 搭建SpringBoot工程

  • 添加Mybatis起步依赖、添加Mysql驱动依赖

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.1.3</version>
    </dependency>
    
    <!--MySql驱动-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    
  • 编写DataSource
    spring:
    datasource:
    url: jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    name: root
    password: "123456"
    driver-class-name: com.mysql.cj.jdbc.Driver

  • Mybatis相关配置

    Mybatis配置

    mybatis:
    #Mapper的映射文件路径
    mapper-locations:
    classpath: mapper/*.xml
    #此处指定Mybatis的核心配置文件
    config-location:
    classpath: Mybatis-config.xml

    # 配置数据源
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mydb?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
    spring.datasource.name=root
    spring.datasource.password=123456
    
    # 配置Mybatis
    mybatis.config-location=classpath:mybatis/Mybatis-config.xml
    mybatis.mapper-locations= classpath:mybatis/mapper/*.xml
    
    • 声明Mapper接口,标注Mapper注解, 给Mapper接口绑定XML
  • 定义表和实体类

  • 编写Dao和Mapper文件 / 或注解方式

  • 测试

SpringBoot 原理分析之 Condition条件判断
  • Condition条件判断 有选择性的实现创建Bean的操作。

  • 使用

    • 创建一个condition包,在该包有创建一个类实现Condition接口,重写boolean matches()方法。

    • 然后在config包中创建一个配置类,该配置类用来注册我们自己的bean。

    • 在我们注册我们自定义bean的方法上写上@Conditional注解,@Conditional(ClassCondition.class)

    • @Conditional(ClassCondition.class) 然后将我们自定义的条件类写到注解中。只要@Conditional注解中的条件类中的boolean matches()方法
      返回true 那么就注册该bean,如果boolean matches()方法返回值为false那么就不注册该bean。

    • boolean matches()方法中用来定义在什么条件下一个Bean会被创建,什么条件下不能创建该Bean

    • boolean matches()方法中有两个形式参数
      @param conditionContext 上下文对象、环境对象
      @param annotatedTypeMetadata 注解的源对象, 可以获取注解定义的属性值

    • 通过 @param annotatedTypeMetadata参数 获取注解的参数值

      Map<String, Object> annotationAttributes = annotatedTypeMetadata.getAnnotationAttributes(ConditionOnClass.class.getName());
      String[] value = (String[]) annotationAttributes.get("value");

SpringBoot 原理分析之 切换内置Web服务器

  • SpringBoot的Web环境中,默认使用的内置Web无服务是TomCat,SpringBoot中一共内置了4种Web服务器,可以切换使用,

  • 怎么查看哪四个Web服务器?
    在org.springframework.boot.autoconfigure.web.embedded下,有四个服务器.

  • 切换服务器

    • 第一步在 spring-boot-starter-web 场景启动器中 首先排除TomCat

      org.springframework.boot
      spring-boot-starter-web


      spring-boot-starter-tomcat
      org.springframework.boot


    • 第二步 加入所要切换的服务器的依赖

      org.springframework.bootspring-boot-starter-jetty

SpringBoot 原理分析之 @Enable* 注解

  • 在SpringBoot中通过了很多@Enable开头的注解,这些注解都是用于动态开启某些功能的,其底层原理是使用@Import注解导入一些配置类,从而实现Bean的动态加载。

SpringBoot 原理分析之 @Import注解

  • @Enable注解底层依赖于@Import注解导入一些类,使用@Import注解的类会被Spring加载到IOC容器中,而@Import注解提供了四种使用方式来注册Bean:

    • 导入Bean实体类 可以将该bean实体类注册到Spring容器中 @Import(User.class)
      直接注册实体类

    • 导入配置类 可以将一个配置类中配置的所有bean都注册到容器中 @Import(UserConfig.class)
      在config配置类中注册Bean, 然后用@Import注解来注册整个配置类

    • 导入ImportSelect实现类,一般用于加载配置文件中的类。 @Import(MyImportSelector.class)

      第一步: 首先自定义个MyImportSelector类,使该类实现ImportSelector接口,然后重写其中的String[] selectImports()方法。

      第二步: 然后在selectImports()方法中, 返回 return new String[]{"com.shi.boot.bean.User", "com.shi.boot.bean.Product"};
      注册哪个类就写哪个类的全限定名称

    • 导入 ImportBeanDefinitionRegister实现类 @Import(MyImportBeanDefinitionRegister.class)

      第一步: 首先自定义一个MyImportBeanDefinitionRegister类,然后该类去实现ImportBeanDefinitionRegistrar接口。

      第二步: 重写 public void registerBeanDefinitions()方法

              //添加User.class
              AbstractBeanDefinition userBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
              registry.registerBeanDefinition("user",userBeanDefinition);
         
              //添加Product.class
              AbstractBeanDefinition productBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Product.class).getBeanDefinition();
              registry.registerBeanDefinition("product",productBeanDefinition);
      

SpringBoot 原理分析之 @EnableConfiguration注解

  • @EnableConfiguration注解内部使用了@Import注解导入了一个AutoConfigurationImportSelector.class,来加载配置类。
    @Import(AutoConfigurationImportSelector.class)

  • AutoConfigurationImportSelector.class类中有一个 List getCandidateConfigurations()方法,
    该方法通过SpringFactoriesLoader()方法获取到一个List集合,该集合中存放的都是需要加载的类。

  • SpringFactoriesLoader()方法从 META-INF/spring.factories文件中获取相关的配置类信息,该文件中定义了大量的配置类,当SpringBoot启动的时候
    会自动加载这些配置类,初始化Bean。

  • 但是并不是所有的Bean都会被初始化, 只有满足Condition条件的类,才会被初始化。

自定义Starter

  • 具体步骤

    • 第一步: 创建 redis-spring-boot-autoconfigure模块

    • 第二步: 创建redis-spring-boot-starter 该依赖去依赖 redis-spring-boot-autoconfigure模块

    • 第三步: redis-spring-boot-autoconfigure模块初始化Jedis的Bean。

    • 第四步: 定义META-INF/spring.factories文件

    • 第五步: 在测试工程中引入redis-spring-boot-starter 依赖,测试获取Jedis的Bean。

SpringBoot的监听机制

  • SpringBoot的监听机制是对java提供的监听机制的一种封装

  • Java监听机制有以下几个角色

    • 事件: Event对象 继承Java.util.EventListener。

    • 事件源: Source(Object) 任意对象Object

    • 监听器: Listener对象 实现Java.util.EventListener接口

  • SpringBoot项目启动的时候会提供几个监听器的回调,我们可以实现这些监听器的接口,在项目启动时完成一些操作。

以下两个接口功能相同,都是在项目启动成功后第一时间被调用

 - CommandLineRunner   会在项目启动后被自动调用该类中的run()方法,该方法中的args参数可以获取 program arguments定义的参数。

 - ApplicationRunner   会在项目启动后被自动调用该类中的run()方法,该方法中的args参数可以获取 program arguments定义的参数。

以下两个方法不会被自动调用,需要配置以下才可以使用。需要在resources下创建META-INF/spring.factories文件,然后在该文件中配置(key=value)
当在spring.factories配置了以下两个类的时候,类中的方法就会被自动调用。

 - ApplicationContextInitializer  

     该类中的 void initialize()方法,会在项目初始化打印完banner图标后执行,一般用于在容器还没有准备一些IOC容器之前
     就检测一些资源是否存在。
   
 - SpringApplicationRunListener

      该类中定义了SpringBoot项目从启动到运行到结束各个声明周期节点的方法,如果我们需要在某一个节点上执行一段代码,就使用其中的方法。

SpringBoot监控 之 Actuator

  • SpringBoot自带的监控功能Actuator(调节器),可以帮助我们实现对程序内部运行情况的监控,比如Bean加载情况、配置属性、日志信息等等。

  • 具体使用步骤

    • 第一步: 导入依赖

      org.springframework.bootspring-boot-starter-actuator
    • 第二步: 访问 http://localhost:8080/actuator
      访问 http://localhost:8080/actuator/health

      会显示一些json字符串,然后通过https://www.json.cn/,查看这些json的详细信息

    • 第三步: 给Actuator配置各种参数

      # 配置actuator 监控info
      info.name=ShiGe
      info.age=18
      
      # 开启Actuator 监控 健康检查的完整信息
      management.endpoint.health.show-details=always
      
      #开启Actuator.所有监测项 (将所有监控EndPoint暴露)
      management.endpoints.web.exposure.include=*
      

SpringBoot监控 之 SpringBoot Admin

  • SpringBoot Admin是一个开源项目,用于管理和监控SpringBoot应用程序,底层还是使用Actuator。

  • SpringBoot Admin分为两个角色一个是客户端(Client)、一个是服务器端(Server)。

  • 应用程序作为SpringBoot Admin Client 向 SpringBoot Admin Server注册

  • SpringBoot Admin Server 提供UI界面,来展示该应用程序的Actuator endpoints上的信息。

  • 具体使用步骤

server部分

- 创建一个Admin Server模块(新建一个项目模块)
 
- 导入一个spring-boot-starter-server
    <!--SpringBoot Admin Server-->
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-server-ui</artifactId>
        <version>2.4.1</version>
    </dependency>

- 在引导类上开始监控功能 @EnableAdminServer
   在Server启动类上加@EnableAdminServer注解, 代表开启监控功能

Client部分

- 创建admin-client模块(新建一个项目模块)

- 引入admin-starter-client依赖
    <!--SpringBoot Admin Client-->
    <dependency>
        <groupId>de.codecentric</groupId>
        <artifactId>spring-boot-admin-client</artifactId>
  <version>2.4.1</version>
    </dependency>

- 在配置文件中配置相关信息 admin.server地址等等

    # 指定admin.server的地址
    spring.boot.admin.client.url=http://localhost:9000
    
    #开启Actuator的速配杨浦监控项
    management.endpoints.web.exposure.include=*
    
    #开启健康检查的详细信息
    management.endpoint.health.show-details=always

- 启动admin.server 和admin.client 访问server

SpringBoot项目部署

  • SpringBoot 支持两种打包方式 jar 和 war

    • jar 在右侧Maven工具栏位置点击package

    • war

      需要在pom.xml中先将jar包改为war包 <packaging>war</packaging>
      
      然后让主启动类去继承 extends SpringBootServletInitializer 
      
      然后重写其中的一个方法
      
           @Override
           protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
                return builder.sources(Springboot13AdminServerApplication.class);
           }
      
      然后重新打包,然后将该war包放到Tomcat服务器的webapps文件夹下,然后就可以访问了。(此时访问路径多了一层springboot)