小编带着小白看springboot源码5

上一节走了一遍从浏览器发出请求到得到向页面的流程,基本的功能是已经实现了。但是现在啊,我想自定义一个拦截器(拦截器可以做用户登录验证,如果登录了,就让你通过,如果没有登录,就重定向登录页面),这里就不复杂了,简单实现以下原理,除了不拦截“/hello”请求,其他请求我都拦截并跳转到index.html。

1.了解springboot的配置类格式

  springboot的配置类最常见的就是在类上面标注@Configuration,表示这是一个配置类(就是以前的xml);

  第一种:在配置类的里面就有很多的@Bean标注的方法(就是以前的),方法名是id,方法返回值是class;

  第一种扩充:标注了@Bean的方法里面返回值匿名内部类的形式

  第二种:在配置类里面还写个静态内部类,静态内部类里面也有@Bean以及一些重写的方法。

  第三种:配置类继承某个类,重写了父类方法

  只要是想添加组件,你自定义的@Bean,可以放在任意的配置类中(标了@Configuration注解,或者写在有main方法的主配置类中)

  配置类用的比较多的就是这几种,还有一些其他的可以自己多查查资料,或者分析一下源码。

  首先这种直接加@Bean的方式就不说了,先说说第三种(这种常用啊),再说说第一种的扩充。第二种就不说了,我们现阶段用不到,不过看springboot自动配置类里面大量用到这种方式,所以这就导致了springboot就那几十个自动配置类,就几乎配置了web应用所有组件。

  1. 第三种的方式

  在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的学习方式,跟着我的或者别的大佬的教程,源码走一遍,只是看完了一两遍效果不大,吃碗饭的功夫就忘记了(亲测!),要想自己理解,还是需要自己多走走源码,走个五六遍,七八遍,你会拨开云雾见天明.....