栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring Boot 2学习笔记

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring Boot 2学习笔记

【注:本笔记参照雷神公开课程所做笔记,仅学习使用】

一、Spring Boot入门程序 1.1 创建Maven工程,添加配置

在pom.xml里添加配置


	org.springframework.boot
	spring-boot-starter-parent
	2.3.4.RELEASE



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

1.2 创建主程序
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;

@SpringBootApplication
public class MainApplication {

    public static void main(String[] args) {
        SpringApplication.run(MainApplication.class, args);
    }
}
1.3 业务编写
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    @RequestMapping("/hello")
    public String handler01(){
        return "Hello, Spring boot 2!";
    }
}
1.4 运行代码
    运行MainApplication类在浏览器输入http://localhost:8080/hello
1.5 设置配置

可以在resource文件夹中创建application.properties文件,其中可以设置配置。

二、依赖管理 2.1 starter场景启动器
    spring-boot-starter-*,其中的*代表某一种场景只要引入starter,这个场景的所有常规需要的依赖都自动引入
    Springboot所有支持的场景:链接第三方starter:*-spring-boot-starter所有场景启动器依赖,最底层的依赖,都会依赖spring-boot-starter

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

2.2 无需关注版本号,自动版本仲裁
    引入依赖默认都可以不写版本号引入非版本仲裁的jar,要写版本号
2.3 可以修改默认版本号
    查看spring-boot-dependencies里面规定当前依赖的版本用的key。在当前项目里面重写配置,如下面的代码。

	5.1.43

三、自动配置特性 3.1 自动配置Tomcat

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

3.2 自动配置SpringMVC

引入了SpringMVC的全套组件自动配置SpringMVC的常用组件 3.3 自动配置Web的常见功能

SpringBoot已经自动配置好了web开发的所有场景,比如字符编码问题自动配置解决

3.4 自动配置了包结构
    主程序所在的包及其下面的所有子包都会默认扫描无需包扫描配置如果路由不想放在主程序包下,即扫描不到时,可以改变扫描路径,使用@SpringBootApplication(scanbasePackages=“com...”)
@SpringBootApplication等同于:
	@SpringBootConfiguration
	@EnableAutoConfiguration
	@ComponentScan("com.lun")
3.5 各种配置拥有默认值

默认配置最终都是映射到某个类上配置文件的值最终会绑定每个类上,这个类会在容器中创建对象 3.6 按需加载自动配置项

有很多的starter,引入了哪些场景这个场景的自动配置才会开启SpringBoot的所有自动配置功能都在 spring-boot-autoconfigure 包里面 四、注解详解 4.1 @Configuration

    @Configuration告诉SpringBoot这是一个配置类配置类里面使用@Bean注解,给容器添加组件,以方法名作为组件的id,返回类型就是组件的类型,返回值是在容器中的实例配置类本身也是组件Full全配置:如果@Configuration里的proxyBeanMethods值是true(默认),意思是保证每个@Bean方法被调用多少次返回的组件都是单实例的。去容器中找组件。Lite轻量级:如果@Configuration里的proxyBeanMethods值是false,意思是调用实例是每一次调用都会产生一个新的对象

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

import com.atguigu.boot.bean.Pet;
import com.atguigu.boot.bean.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;


@Configuration(proxyBeanMethods = false)  //这个注解,告诉SpringBoot这是一个配置类
public class MyConfig {

    @Bean   //给容器添加组件,以方法名作为组件的id,返回类型就是组件类型,返回的值就的组件是实例
    public User user01(){
        return new User("zhangsan", 18);
    }

    @Bean("tom")
    public Pet tomcatPet(){
        return new Pet("tomcat");
    }
}
import com.atguigu.boot.bean.Pet;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;



@SpringBootApplication
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);
    }
}
4.2 @Conditional

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

以@ConditionalOnBean(name = “tom”)为例,这个注解加在@Bean之前,就意味着容器中存在tom的实例时,才可以创建这个Bean此标签还可以加在类上,意思是如果容器中有tom时候,这个类的方法才能实现
4.3 @importResource

如果bean是由xml文件导入的,此时可以在配置文件类上使用@importResource注解,让其导入xml文件

@importResource("classpath:beans.xml")



    
        
        
    

    
        
    


4.4 配置绑定

目的:使用Java读取到properties文件中的内容,并且把它封装到JavaBean中。
1. @ConfigurationProperties + @Component

配置文件里有配置

mycar.brand = BYD
mycar.price = 100000

给Java实例添加注解@Component,@ConfigurationProperties(prefix = "")
先创建容器,才会拥有SpringBoot的功能

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "mycar")//这里的mycar是properties中的mycar
public class Car {

    private String brand;
    private Integer price;

    public Car() {
    }

    public Car(String brand, Integer price) {
        this.brand = brand;
        this.price = price;
    }

    public Integer getPrice() {
        return price;
    }

    public void setPrice(Integer price) {
        this.price = price;
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    @Override
    public String toString() {
        return "Car{" +
                "brand='" + brand + ''' +
                ", price=" + price +
                '}';
    }
}

自动装配

@RestController
public class HelloController {

    @Autowired
    Car car;
    
    @RequestMapping("/car")
    public Car car(){
        return car;
    }
}

2. @EnableConfigurationProperties + @ConfigurationProperties

在配置类里开启配置绑定

@EnableConfigurationProperties(Car.class)
public class MyConfig {
...
}

自动注入到容器中

@ConfigurationProperties(prefix = "mycar")
public class Car {
...
}
五、SpringBoot技巧 5.1 最佳应用实战技巧

1. 引入场景依赖

官方文档

2. 查看自动配置了哪些(选做)

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

3. 是否需要修改

参照文档修改配置项

参照文档自己分析。xxxxProperties绑定了配置文件的哪些。 自定义加入或者替换组件

@Bean、@Component… 自定义器 XXXXXCustomizer 5.2 Lombok简化开发

    Lombok用标签方式代替构造器、getter/setter、toString等代码。
    spring boot已经管理Lombok;

    引入依赖

    
    	org.projectlombok
    	lombok
    
    

    安装Lombok插件

    使用

    简化JavaBean代码

    import lombok.*;
    
    @ToString           //toString()方法
    @Data               //getter/setter方法
    @AllArgsConstructor //全参构造器
    @NoArgsConstructor  //无参构造器
    @EqualsAndHashCode  //重写equals和hashcode方法
    public class Pet {
        private String name;
    }
    

    简化日志开发

    @Slf4j
    public class HelloController {
        @RequestMapping("/hello")
        public String handler01(){
            log.info("....");
            return "Hello, Spring boot 2!";
        }
    }
    
5.3 dev-tools项目热更新

    使用dev-tools项目热更新

    添加依赖

    
    	org.springframework.boot
    	spring-boot-devtools
    	true
    
    

    当修改代码之后,按Ctrl+F9即可

5.4 yaml配置文件

1. 基本语法

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

2. 实例

person:
  userName: zhangsan
  boss: true
  birth: 2022/3/1
  age: 22
  interests:
    - 篮球
    - 足球
  animal: [阿猫,阿狗]
  score: {english: 80,math: 90}
  salarys:
    - 999.99
    - 999.98
  pet:
    name: 阿狗
    weight: 99.99
  allPets:
    sick:
      - {name: 阿狗, weight: 99.99}
      - name: 阿猫
        weight: 88.88
      - name: 阿猪
        weight: 77.77
    health:
      - {name: 阿虫, weight: 3.3}
import lombok.Data;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

@ConfigurationProperties(prefix = "person")
@Component
@ToString
@Data
public 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;
}
5.5 自定义类配置的代码提示
    自定义的类中自己定义的属性往往在yaml中书写时没有提示,那么可以使用自定义类配置的代码提示引入依赖
    
    	org.springframework.boot
        spring-boot-configuration-processor
        true
    
    
六、Web开发 6.1 静态资源访问

    静态资源默认的文件夹名:/static 、 /public 、 /resources 、 /meta-INF/resources

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

    当请求进来时,会先去匹配动态请求,如果请求未找到则再去静态资源中找,静态资源也找不到则返回404

    静态资源默认映射 @PostMapping("/saveuser") public Person saveuser(Person person){ return person; }

    运行结果,将请求的值,和JavaBean里面的属性进行自动绑定。

    6.8 响应json数据

      如果想返回json数据的话,需要引入依赖

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

      只需要在控制层的方法上添加@ResponseBody注解即可

      import com.atguigu.boot.bean.Person;
      import org.springframework.stereotype.Controller;
      import org.springframework.web.bind.annotation.GetMapping;
      import org.springframework.web.bind.annotation.ResponseBody;
      
      import java.util.Date;
      
      @Controller
      public class ResponseTestController {
      
          @ResponseBody
          @GetMapping("/test/person")
          public Person getPerson(){
              Person person = new Person();
              person.setAge(28);
              person.setBirth(new Date());
              person.setUserName("zs");
              return person;
          }
      }
      
    七、Thymeleaf模板引擎 7.1 Thymeleaf使用

    1. 引入starter

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

    2. 自动配置好thymeleaf

    自动配好的策略

    所有thymeleaf的配置值都在ThymeleafProperties配置好了 SpringTemplateEngine配好了 ThymeleafViewResolver我们只需要直接开发页面 7.2 thymeleaf语法

    在html标签中,加上themeleaf命名空间

    
    

    基本语法

    ${…}:变量取值,获取请求域、session域或对象的值*{…}:选择变量,获取上下文对象的值#{…}:消息,获取国际化等值@{…}:链接,生成链接~{…}:片段表达式,引入公共页面片段

    字面量

    文本值: ‘one text’ , ‘Another one!’ ,…数字: 0 , 34 , 3.0 , 12.3 ,…布尔值: true , false空值: null变量: one,two,… 变量不能有空格

    文本操作

    字符串拼接: +变量替换: |The name is ${name}|

    数学运算

    运算符: + , - , * , / , %布尔运算运算符: and , or一元运算: ! , not

    比较运算

    比较: > , < , >= , <= ( gt , lt , ge , le )等式: == , != ( eq , ne )

    条件运算

    If-then: (if) ? (then)If-then-else: (if) ? (then) : (else)Default: (value) ?: (defaultvalue)

    特殊操作

    无操作: _

    八、单元测试Junit5

    Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库

    8.1 Junit5常用注解

      @Test:表示方法是测试方法。但是与JUnit4的@Test不同,他的职责非常单一不能声明任何属性,拓展的测试将会由Jupiter提供额外测试

      @DisplayName:为测试类或者测试方法设置展示名称

      import org.junit.jupiter.api.DisplayName;
      import org.junit.jupiter.api.Test;
      
      @DisplayName("junit5功能测试类")
      public class testJunit5 {
      
          @DisplayName("测试displayname注解")
          @Test
          void testDisplayName(){
              System.out.println(1);
          }
      }
      

      @BeforeEach:表示在每个单元测试之前执行
      @AfterEach:表示在每个单元测试之后执行

      package com.atguigu.boot;
      
      import org.junit.jupiter.api.AfterEach;
      import org.junit.jupiter.api.BeforeEach;
      import org.junit.jupiter.api.DisplayName;
      import org.junit.jupiter.api.Test;
      
      @DisplayName("junit5功能测试类")
      public class testJunit5 {
      
          @DisplayName("测试displayname注解")
          @Test
          void testDisplayName(){
              System.out.println(1);
          }
      
          @BeforeEach
          void testBeforeEach(){
              System.out.println("测试就要开始了");
          }
      
          @AfterEach
          void testAfterEach(){
              System.out.println("测试就要结束了");
          }
      }
      

      @BeforeAll:表示在所有单元测试之前执行
      @AfterAll:表示在所有单元测试之后执行

      @Tag:表示单元测试类别,类似于JUnit4中的@Categories

      @Disabled:表示测试类或测试方法不执行

      @Timeout:表示测试方法运行如果超过了指定时间将会返回错误

        @Timeout(value = 500, unit = TimeUnit.MICROSECONDS)
        @Test
        void testTimeout() throws InterruptedException {
            Thread.sleep(500);
        }
    
      @ExtendWith:为测试类或测试方法提供扩展类引用@RepeatedTest(n):重复测试n次
    8.2 断言机制 8.2.1 简单断言

    断言Assertion是测试方法中的核心部分,用来对测试需要满足的条件进行验证这些断言方法都是org.junit.jupiter.api.Assertions的静态方法检查业务逻辑返回的数据是否合理,所有的测试运行结束以后,会有一个详细的测试报告

    方法说明
    assertEquals判断两个对象或两个原始类型是否相等
    assertNotEquals判断两个对象或两个原始类型是否不相等
    assertSame判断两个对象引用是否指向同一个对象
    assertNotSame判断两个对象引用是否指向不同的对象
    assertTrue判断给定的布尔值是否为 true
    assertFalse判断给定的布尔值是否为 false
    assertNull判断给定的对象引用是否为 null
    assertNotNull判断给定的对象引用是否不为 null

    前边的断言失败了,后面的代码都不会执行

    import com.atguigu.boot.bean.Person;
    import org.junit.jupiter.api.Assertions;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    import static org.junit.jupiter.api.Assertions.assertSame;
    
    public class testAssertions {
    
        @DisplayName("测试简单断言")
        @Test
        void testSimpleAssertions(){
            int cal = cal(2, 3);
            // 是否计算的值是5
            assertEquals(5, cal, "业务逻辑计算失败");
            // 是否是同一个对象
            Person p1 = new Person();
            Person p2 = new Person();
            assertSame(p1, p2,"两个对象不一样");
        }
    
        int cal(int i, int j){
            return i+j;
        }
    }
    
    8.2.2 数组断言

    比较数组是否相等

    @DisplayName("数组断言")
        @Test
        void array(){
            assertArrayEquals(new int[]{2, 1}, new int[]{1, 2}, "数组内容不相等");
        }
    
    8.2.3 组合断言

    一个断言中有好多个断言

    @DisplayName("组合断言")
    @Test
    void all(){
    	assertAll("test",
    		()->assertTrue(true && true, "结果不是true"),
    		()->assertEquals(1 ,2, "结果不是1"));
    	System.out.println(1);
    }
    
    8.2.4 异常断言

    程序肯定会有异常,如果没有异常则返回“异常居然正常运行”

    @DisplayName("异常断言")
    @Test
    void testException(){
    	assertThrows(ArithmeticException.class, ()->{int i = 10/0;}, "业务逻辑居然正常运行");
    }
    
    8.2.5 超时断言
    @Test
    @DisplayName("超时测试")
    public void timeoutTest() {
        //如果测试方法时间超过1s将会异常
        Assertions.assertTimeout(Duration.ofMillis(1000), () -> Thread.sleep(500));
    }
    
    8.2.6 快速失败

    通过 fail 方法直接使得测试失败

    @Test
    @DisplayName("fail")
    public void shouldFail() {
    	fail("This should fail");
    }
    
    8.3 Assumptions假设

    assumptions类似于断言,不同之处在于不满足的断言assertions会使得测试方法失败,而不满足的前置条件只会使得测试方法的执行终止前置条件可以看成是测试方法执行的前提,当该前提不满足时,就没有继续执行的必要

    import org.junit.jupiter.api.Assumptions;
    import org.junit.jupiter.api.DisplayName;
    import org.junit.jupiter.api.Test;
    
    public class testAssumptions {
    
        @DisplayName("测试前置条件")
        @Test
        void testassumptions(){
            Assumptions.assumeTrue(true, "结果不是true");
            System.out.println(1111);
        }
    }
    
    九、 数据访问 9.1 配置Druid数据源和MySQL数据库

    1. 导入JDBC依赖

    
    	org.springframework.boot
    	spring-boot-starter-data-jdbc
    
    

    2. 导入MySQL数据库依赖

    
    	mysql
    	mysql-connector-java
    
    

    3. 导入Druid-starter数据源依赖

    
        com.alibaba
        druid-spring-boot-starter
        1.1.17
    
    

    4. 在application.yaml中添加配置

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/
        username: root
        password: 123
        driver-class-name: com.mysql.jdbc.Driver
    
    9.2 注解方式整合MyBatis

    1. 创建项目

    添加MyBatis、MySQL和Web

    2. 已经自动导入了数据库相关的依赖

        
            
                org.springframework.boot
                spring-boot-starter-web
            
            
                org.mybatis.spring.boot
                mybatis-spring-boot-starter
                2.2.2
            
    
            
                mysql
                mysql-connector-java
                runtime
                5.1.49
            
            
                org.springframework.boot
                spring-boot-starter-test
                test
            
            
                org.projectlombok
                lombok
            
        
    

    3. 编写Mapper接口

    import com.hkd.bean.User;
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Select;
    
    @Mapper
    public interface UserMapper {
    
        @Select("select * from user1 where id = #{id}")
        public User getId(int id);
    }
    

    4. 编写Controller

    import com.hkd.bean.User;
    import com.hkd.service.UserService;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    @Slf4j
    @Controller
    public class UserController {
    
        @Autowired
        UserService userService;
    
        @ResponseBody
        @GetMapping("/user")
        public User getId(@RequestParam("id") int id) {
            return userService.getId(id);
        }
    }
    

    5. 编写Service层

    import com.hkd.bean.User;
    import com.hkd.mapper.UserMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    @Service
    public class UserService {
    
        @Autowired
        UserMapper userMapper;
    
        public User getId(int id){
            return userMapper.getId(id);
        }
    }
    

    6. 编写配置文件

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/jdbc
        username: root
        password: 123
    
        mvc:
          hiddenmethod:
            filter:
              enabled: true #开启页面表单的Rest功能
    

    7. 编写Bean

    import lombok.Data;
    
    @Data
    public class User {
        private Integer id;
        private String username;
        private String password;
    }
    

    8. 数据库不在此展示了,展示效果图如下

    9.3 整合MyBatis-Plus

    1. 引入依赖

    由于mybatis-plus已经给我们引入了jdbc、mybatis,所以我们只需要引入这一个依赖即可

    
    	
    		org.springframework.boot
    		spring-boot-starter-web
    	
    	
    		mysql
    		mysql-connector-java
    		runtime
    		5.1.49
    	
    	
    		org.springframework.boot
    		spring-boot-starter-test
    		test
    	
    	
    		org.projectlombok
    		lombok
    	
    	
    		com.baomidou
    		mybatis-plus-boot-starter
    		3.5.1
    	
    
    

    2. mybatis-plus自动配置

    MybatisPlusAutoConfiguration配置类,MybatisPlusProperties配置项绑定。SqlSessionFactory自动配置好,底层是容器中默认的数据源。mapperLocations自动配置好的,有默认值classpath*:/mapper*.xml,这表示任意包的类路径下的所有mapper文件夹下任意路径下的所有xml都是sql映射文件。 建议以后sql映射文件放在 mapper下。容器中也自动配置好了SqlSessionTemplate。@Mapper 标注的接口也会被自动扫描,建议直接@MapperScan(“com.lun.boot.mapper”)批量扫描。

    MyBatisPlus优点之一:只需要我们的Mapper继承MyBatisPlus的baseMapper 就可以拥有CRUD能力,减轻开发工作。

    十、拦截器 10.1 拦截器的使用
      编写一个拦截器实现HandlerInterceptor接口拦截器注册到容器中(实现WebMvcConfigurer的addInterceptors())指定拦截规则【注意,如果是拦截所有,静态资源也会被拦截】
    import org.springframework.web.servlet.HandlerInterceptor;
    import org.springframework.web.servlet.ModelAndView;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    
    
    public class LoginInterceptor implements HandlerInterceptor {
    
        
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            //登录检查
            HttpSession session = request.getSession();
            Object loginUser = session.getAttribute("loginUser");
            if (loginUser != null)
                return true;    //放行
            request.setAttribute("msg","请先登录");
            request.getRequestDispatcher("/").forward(request, response);
            return false;
        }
    
        
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    
        }
    
        
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    
        }
    }
    
    import com.hkd.interceptor.LoginInterceptor;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class AdminWebConfig implements WebMvcConfigurer {
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor())
                    .addPathPatterns("/**")     // 拦截所有请求,包括静态资源
                    .excludePathPatterns("/css/**", "/fonts/**", "/img/**", "/js/**");  //放行
    
        }
    }
    
    10.2 拦截器的执行时机和原理
      根据当前请求,找到HandlerExecutionChain(可以处理请求的handler以及handler的所有拦截器)先来顺序执行所有拦截器的preHandle()方法。如果当前拦截器preHandle()返回为true。则执行下一个拦截器的preHandle()如果当前拦截器返回为false。直接倒序执行所有已经执行了的拦截器的 afterCompletion()如果任何一个拦截器返回false,直接跳出不执行目标方法。所有拦截器都返回true,才执行目标方法。倒序执行所有拦截器的postHandle()方法。前面的步骤有任何异常都会直接倒序触发 afterCompletion()页面成功渲染完成以后,也会倒序触发 afterCompletion()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785420.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号