带着萌新看springboot源码05
上一节走了一遍从浏览器发出请求到得到向页面的流程,基本的功能是已经实现了。但是现在啊,我想自定义一个拦截器(拦截器可以做用户登录验证,如果登录了,就让你通过,如果没有登录,就重定向登录页面),这里就不复杂了,简单实现以下原理,除了不拦截“/hello”请求,其他请求我都拦截并跳转到index.html。
1.了解springboot的配置类格式
springboot的配置类最常见的就是在类上面标注@Configuration,表示这是一个配置类(就是以前的xml);
第一种:在配置类的里面就有很多的@Bean标注的方法(就是以前的<bean id="" class=""></bean>),方法名是id,方法返回值是class;
第一种扩充:标注了@Bean的方法里面返回值匿名内部类的形式
第二种:在配置类里面还写个静态内部类,静态内部类里面也有@Bean以及一些重写的方法。
第三种:配置类继承某个类,重写了父类方法
只要是想添加组件,你自定义的@Bean,可以放在任意的配置类中(标了@Configuration注解,或者写在有main方法的主配置类中)
配置类用的比较多的就是这几种,还有一些其他的可以自己多查查资料,或者分析一下源码。
首先这种直接加@Bean的方式就不说了,先说说第三种(这种常用啊),再说说第一种的扩充。第二种就不说了,我们现阶段用不到,不过看springboot自动配置类里面大量用到这种方式,所以这就导致了springboot就那几十个自动配置类,就几乎配置了web应用所有组件。
2. 第三种的方式
在springboot中,提供了一组接口,xxxConfigurer,这种接口就是让你扩展功能的,比如你想添加一个自定义的视图解析器,就可以实现这个接口,重写configureViewResolvers方法,原理后面会讲到。
现在以WebMvcConfigurer接口为例,初步认识这个东西。WebMvcConfigurer顾名思义,就是webmvc配置器,可以让你扩充webmvc里面的功能。
在这里不得不说一下,面向接口和面向抽象类编程的区别了。面向接口变成就是你要实现接口中【所有所有】的方法,管你用不用得上;但是,假如有个抽象类去实现了这个接口(抽象类里面都是空方法,还可以自己添加新的方法),然后我们只需要去继承这个抽象类,重写其中我们需要的方法就可以了,用多少,就重写多少。
基于这种思想,springboot提供了一个抽象类WebMvcConfigurerAdapter去实现WebMvcConfigurer接口,所以我们只需要继承WebMvcConfigurerAdapter就可以了。
现在就来自定义一个拦截器,拦截器的原理就不说了,就三个方法,preHandle(调用controller里面方法前首先调用此方法,登录验证主要在这里),postHandle(后),afterCompletion(返回页面之后),springboot定义拦截器(可以实现HandlerInterceptor接口,也可以继承HandlerInterceptorAdapter抽象类,原因跟上面一样),我这里就是继承的方式。

上图下面的是我自己写的逻辑,就是转发到index.html页面,emmmm....我也不知道这个index.html会不会被视图解析器解析,反正写“/index.html”可以,直接写“index”也行,自己尝试一下吧!
写个继承抽象类WebMvcConfigurerAdapter的配置类

这种很方便吧,而且WebConfigurerAdapter内部方法很多,可以重写的方法很多,自己去尝试啊 。
3.第一种扩充的方式
随便找个标有@Configuration或者相关的配置类,我就在主配置类配置了。

这样配置也行,这种比上面一种简洁一点,不用特意写一个配置类了。
看到这里,肯定有很多小伙伴会惊呼,我日了狗哦,为什么这样就会配置到应用中啊?你就实现了一个方法或者把一个xxxconfigurer的匿名类丢到容器(匿名内部类----->继承xxxConfiguratorAdapter-------->实现xxxConfigurer接口),springboot就会找到组件并用起来,这么厉害。
下面就来粗略看看原理(不用想,还是在自动配置类里面,记住,一切原理都在自动配置类里面)
4.一起看看xxxConfigurer原理(以WebMvcConfigurer为例)
首先打开自动配置类------->WebMvcAutoConfiguration,找到

这个类EnableWebMvcConfiguration也是一个本自动配置类的一个静态内部类,下面重写的方法也就是调用父类的一些方法(这里偷个懒,就不带着去看了),所以重点就是父类DelegatingWebMvcConfiguration

打开父类可以看到,而且这个此类下面所有重写的方法,就是调用configurers这个容器的方法。


打开这个容器WebMvcConfigurerComposite,你会发现这里就是遍历所有的configurers,挨个执行每个方法。


所有的基本逻辑说完了,看到这里肯定蒙比了,前面的都忘记的差不多了,这是正常现象。
那么,这里就再总结一下前面的原理,回顾一下:
首先是定义一个继承WebMvcConfigurerAdapter抽象类(WebMvcConfigurer类型)的拦截器,拦截器是一个WebMvcConfigurer类型的------------->实现了addInterceptor(registry)方法添加拦截映射-------------->这个【WebMvcConfigurer】类型的拦截器丢到容器里,供别的组件从容器中获取(springboot大量用这种原理,实现什么功能的组件直接丢到容器中,就不用你操心了)。
然后启动springboot应用,自动配置类加载-------------->加载EnableWebMvcConfiguration.class内部类-------->这个内部类调用父类【DelegatingWebMvcConfiguration】方法--------->父类DelegatingWebMvcConfiguration功能就是从容器中获取获取所有的WebMvcConfigurer类型的组件,运用一定的方式遍历所有的WebMvcConfigurer,并依次运行所有的方法(包括自定义的addInterceptor方法,以及自定义的其他方法都是在这里运行)------------>等待你在浏览器url输入,判断是否满足拦截条件进行拦截
这里就是简单的说了一下WebMvcConfigurer的原理,适合萌新入门使用,想要更深入的可以自己去走走源码,会理解的很清楚的。而且,推荐一个学习springboot的学习方式,跟着我的或者别的大佬的教程,源码走一遍,只是看完了一两遍效果不大,吃碗饭的功夫就忘记了(亲测!),要想自己理解,还是需要自己多走走源码,走个五六遍,七八遍,你会拨开云雾见天明.....
带着萌新看springboot源码05的更多相关文章
- 带着萌新看springboot源码8(spring ioc源码 完)
上一节说到实例化了所有的单实例Bean,后面还有一步遍历 12.完成容器刷新(finishRefresh();) 那个和生命周期有关的后置处理器类型是LifecycleProcessor:监听器原理我 ...
- 带着萌新看springboot源码8(spring ioc源码上)
emmm.....这次先不说springboot原理,先好好回顾一下以前的注解版spring原理,先把spring原理了解清晰了,再看springboot原理更容易. 要说起spring,最重要的就是 ...
- 带着萌新看springboot源码03
上一节讲到了快速新建一个springboot应用,以及springboot的自动配置类起作用的时机,并且一起看了一个自动配置类的源码. 这一节我们来粗略看看当用户在浏览器输入一个url,怎么样返回一个 ...
- 带着萌新看springboot源码12(启动原理 下)
先继续接上一篇,那个启动原理还有一点没说完. 6. afterRefresh(context, applicationArguments); 看这个名字就知道,应该就是ioc容器刷新之后的一些操作了, ...
- 带着萌新看springboot源码11(springboot启动原理 源码上)
通过前面这么多讲解,springboot原理应该也大概有个轮廓了,一些基本的配置,从客户端url到controller(配置一些要用的组件,servlet三大组件,处理器映射器,拦截器,视图解析器这些 ...
- 带着萌新看springboot源码10(springboot+JdbcTemplate+druid)
上一节把springboot和jdbcTemplate大概用法说了一下,以及大概看了一下源码,还说了加载sql文件时的原理. 这一节来看看自动注入JdbcTemplate的原理,顺便用一用Druid数 ...
- 带着萌新看springboot源码09(springboot+JdbcTemplate)
emmm.....常规开局,继续说一下废话,前面简单的说了一下spring的ioc容器创建原理(花了不少时间去看了别人的博客+查了不少资料+自己的理解),相信大家对ioc容器有了一个初步的认识了. s ...
- 带着萌新看springboot源码04
继续开头说些废话,我也不知道什么鬼,每次写着写着经常会写到其他地方去了,太容易分神了. 这次说一下springboot对于springmvc的大概整个流程,以请求动态网页为例 . 1.梳理一下spri ...
- 带着萌新看springboot源码8(spring ioc源码下)
继续接着上一节,到了第六步(温馨提醒,内容有点小多,不过看完ioc原理就差不多了) 6.注册Bean后置处理器(registerBeanPostProcessors(beanFactory)) 最后一 ...
随机推荐
- avue的小白之路
经过几天的看实例,我稍稍了解到了avue,写这个博客主要是最近学习avue的一个总结.. avue是基于vue与element ui的一个框架,强烈建议等了解这其中道理在学习avue会事半功倍:这是我 ...
- ISP PIPLINE (九_1) Denoise 之 space domain denoise
1.空间域噪声类型 1.gauss+possion 2.椒盐噪声(dpc处理已经处理了) 去除空域噪声有哪些方法? 空域噪声一般的思想是对某pixel邻域的pixels进行加权平均. 比如 1.高斯降 ...
- iOS异常捕获和处理
2013年4月份整理的代码,仅作记录: //先宏定义 //发布和未发布状态的日志切换 #ifdef DEBUG //异常栈开关 #define STACK_KEY YES ...
- git diff old mode 100644 new mode 100755
今天执行git diff filename ,出现 old mode 100644 new mode 100755 的提示,如下图: 但是发现文件内容并没有发生改变 想起来中间执行过chmod 的操 ...
- Java IO 整理
1.Java IO中的操作类之间的继承关系 2.在java中使用File类表示文件本身,可以直接使用此类完成文件的各种操作,如创建.删除 3.RandomAccessFile类可以从指定位置开始读取数 ...
- 小程序----选择地理位置 ( wx.chooseLocation ) 和 获取地理位置 (wx.getSetting)
问题来了:假如我第一次使用wx.chooseLocation()获取权限被拒绝,然后使用wx.getSetting()来重新获取权限该怎么做呢? 思路:wx.chooseLocation()有fail ...
- 性能测试学习 第九课--LR12中controller基础知识
1.设计手工场景,理解集合点的策略 2.添加load generator 一.controller基础知识 1.controller的原理 通过场景设计来模拟用户的真实操作并调用vugen中的脚本,然 ...
- LVM学习笔记
LVM Logical Volume Manager Volume management creates a layer of abstraction over physical storage, a ...
- Redis API的原子性分析
在学习Redis的常用操作时,经常看到介绍说,Redis的set.get以及hset等等命令的执行都是原子性的,但是令自己百思不得其解的是,为什么这些操作是原子性的? 原子性 原子性是数据库的事务中的 ...
- [Swift]LeetCode150. 逆波兰表达式求值 | Evaluate Reverse Polish Notation
Evaluate the value of an arithmetic expression in Reverse Polish Notation. Valid operators are +, -, ...