1. 程式人生 > >帶著萌新看springboot原始碼05

帶著萌新看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的學習方式,跟著我的或者別的大佬的教程,原始碼走一遍,只是看完了一兩遍效果不大,吃碗飯的功夫就忘記了(親測!),要想自己理解,還是需要自己多走走原始碼,走個五六遍,七八遍,你會撥開雲霧見天明.....