上一節(jié)走了一遍從瀏覽器發(fā)出請(qǐng)求到得到向頁(yè)面的流程,基本的功能是已經(jīng)實(shí)現(xiàn)了。但是現(xiàn)在啊,我想自定義一個(gè)攔截器(攔截器可以做用戶登錄驗(yàn)證,如果登錄了,就讓你通過(guò),如果沒(méi)有登錄,就重定向登錄頁(yè)面),這里就不復(fù)雜了,簡(jiǎn)單實(shí)現(xiàn)以下原理,除了不攔截“/hello”請(qǐng)求,其他請(qǐng)求我都攔截并跳轉(zhuǎn)到index.html。
1.了解springboot的配置類格式
springboot的配置類最常見的就是在類上面標(biāo)注@Configuration,表示這是一個(gè)配置類(就是以前的xml);
第一種:在配置類的里面就有很多的@Bean標(biāo)注的方法(就是以前的<bean id="" class=""></bean>),方法名是id,方法返回值是class;
第一種擴(kuò)充:標(biāo)注了@Bean的方法里面返回值匿名內(nèi)部類的形式
第二種:在配置類里面還寫個(gè)靜態(tài)內(nèi)部類,靜態(tài)內(nèi)部類里面也有@Bean以及一些重寫的方法。
第三種:配置類繼承某個(gè)類,重寫了父類方法
只要是想添加組件,你自定義的@Bean,可以放在任意的配置類中(標(biāo)了@Configuration注解,或者寫在有main方法的主配置類中)
配置類用的比較多的就是這幾種,還有一些其他的可以自己多查查資料,或者分析一下源碼。
首先這種直接加@Bean的方式就不說(shuō)了,先說(shuō)說(shuō)第三種(這種常用?。?,再說(shuō)說(shuō)第一種的擴(kuò)充。第二種就不說(shuō)了,我們現(xiàn)階段用不到,不過(guò)看springboot自動(dòng)配置類里面大量用到這種方式,所以這就導(dǎo)致了springboot就那幾十個(gè)自動(dòng)配置類,就幾乎配置了web應(yīng)用所有組件。
2. 第三種的方式
在springboot中,提供了一組接口,xxxConfigurer,這種接口就是讓你擴(kuò)展功能的,比如你想添加一個(gè)自定義的視圖解析器,就可以實(shí)現(xiàn)這個(gè)接口,重寫configureViewResolvers方法,原理后面會(huì)講到。
現(xiàn)在以WebMvcConfigurer接口為例,初步認(rèn)識(shí)這個(gè)東西。WebMvcConfigurer顧名思義,就是webmvc配置器,可以讓你擴(kuò)充webmvc里面的功能。
在這里不得不說(shuō)一下,面向接口和面向抽象類編程的區(qū)別了。面向接口變成就是你要實(shí)現(xiàn)接口中【所有所有】的方法,管你用不用得上;但是,假如有個(gè)抽象類去實(shí)現(xiàn)了這個(gè)接口(抽象類里面都是空方法,還可以自己添加新的方法),然后我們只需要去繼承這個(gè)抽象類,重寫其中我們需要的方法就可以了,用多少,就重寫多少。
基于這種思想,springboot提供了一個(gè)抽象類WebMvcConfigurerAdapter去實(shí)現(xiàn)WebMvcConfigurer接口,所以我們只需要繼承WebMvcConfigurerAdapter就可以了。
現(xiàn)在就來(lái)自定義一個(gè)攔截器,攔截器的原理就不說(shuō)了,就三個(gè)方法,preHandle(調(diào)用controller里面方法前首先調(diào)用此方法,登錄驗(yàn)證主要在這里),postHandle(后),afterCompletion(返回頁(yè)面之后),springboot定義攔截器(可以實(shí)現(xiàn)HandlerInterceptor接口,也可以繼承HandlerInterceptorAdapter抽象類,原因跟上面一樣),我這里就是繼承的方式。
上圖下面的是我自己寫的邏輯,就是轉(zhuǎn)發(fā)到index.html頁(yè)面,emmmm....我也不知道這個(gè)index.html會(huì)不會(huì)被視圖解析器解析,反正寫“/index.html”可以,直接寫“index”也行,自己嘗試一下吧!
寫個(gè)繼承抽象類WebMvcConfigurerAdapter的配置類
這種很方便吧,而且WebConfigurerAdapter內(nèi)部方法很多,可以重寫的方法很多,自己去嘗試啊 。
3.第一種擴(kuò)充的方式
隨便找個(gè)標(biāo)有@Configuration或者相關(guān)的配置類,我就在主配置類配置了。
這樣配置也行,這種比上面一種簡(jiǎn)潔一點(diǎn),不用特意寫一個(gè)配置類了。
看到這里,肯定有很多小伙伴會(huì)驚呼,我日了狗哦,為什么這樣就會(huì)配置到應(yīng)用中?。磕憔蛯?shí)現(xiàn)了一個(gè)方法或者把一個(gè)xxxconfigurer的匿名類丟到容器(匿名內(nèi)部類----->繼承xxxConfiguratorAdapter-------->實(shí)現(xiàn)xxxConfigurer接口),springboot就會(huì)找到組件并用起來(lái),這么厲害。
下面就來(lái)粗略看看原理(不用想,還是在自動(dòng)配置類里面,記住,一切原理都在自動(dòng)配置類里面)
4.一起看看xxxConfigurer原理(以WebMvcConfigurer為例)
首先打開自動(dòng)配置類------->WebMvcAutoConfiguration,找到
這個(gè)類EnableWebMvcConfiguration也是一個(gè)本自動(dòng)配置類的一個(gè)靜態(tài)內(nèi)部類,下面重寫的方法也就是調(diào)用父類的一些方法(這里偷個(gè)懶,就不帶著去看了),所以重點(diǎn)就是父類DelegatingWebMvcConfiguration
打開父類可以看到,而且這個(gè)此類下面所有重寫的方法,就是調(diào)用configurers這個(gè)容器的方法。
打開這個(gè)容器WebMvcConfigurerComposite,你會(huì)發(fā)現(xiàn)這里就是遍歷所有的configurers,挨個(gè)執(zhí)行每個(gè)方法。
所有的基本邏輯說(shuō)完了,看到這里肯定蒙比了,前面的都忘記的差不多了,這是正常現(xiàn)象。
那么,這里就再總結(jié)一下前面的原理,回顧一下:
首先是定義一個(gè)繼承WebMvcConfigurerAdapter抽象類(WebMvcConfigurer類型)的攔截器,攔截器是一個(gè)WebMvcConfigurer類型的------------->實(shí)現(xiàn)了addInterceptor(registry)方法添加攔截映射-------------->這個(gè)【W(wǎng)ebMvcConfigurer】類型的攔截器丟到容器里,供別的組件從容器中獲取(springboot大量用這種原理,實(shí)現(xiàn)什么功能的組件直接丟到容器中,就不用你操心了)。
然后啟動(dòng)springboot應(yīng)用,自動(dòng)配置類加載-------------->加載EnableWebMvcConfiguration.class內(nèi)部類-------->這個(gè)內(nèi)部類調(diào)用父類【DelegatingWebMvcConfiguration】方法--------->父類DelegatingWebMvcConfiguration功能就是從容器中獲取獲取所有的WebMvcConfigurer類型的組件,運(yùn)用一定的方式遍歷所有的WebMvcConfigurer,并依次運(yùn)行所有的方法(包括自定義的addInterceptor方法,以及自定義的其他方法都是在這里運(yùn)行)------------>等待你在瀏覽器url輸入,判斷是否滿足攔截條件進(jìn)行攔截
這里就是簡(jiǎn)單的說(shuō)了一下WebMvcConfigurer的原理,適合萌新入門使用,想要更深入的可以自己去走走源碼,會(huì)理解的很清楚的。而且,推薦一個(gè)學(xué)習(xí)springboot的學(xué)習(xí)方式,跟著我的或者別的大佬的教程,源碼走一遍,只是看完了一兩遍效果不大,吃碗飯的功夫就忘記了(親測(cè)!),要想自己理解,還是需要自己多走走源碼,走個(gè)五六遍,七八遍,你會(huì)撥開云霧見天明.....
在這里給大家提供一個(gè)學(xué)習(xí)交流的平臺(tái),Java技術(shù)交流┟ 810309655
具有1-5工作經(jīng)驗(yàn)的,面對(duì)目前流行的技術(shù)不知從何下手,需要突破技術(shù)瓶頸的可以加群。
在公司待久了,過(guò)得很安逸,但跳槽時(shí)面試碰壁。需要在短時(shí)間內(nèi)進(jìn)修、跳槽拿高薪的可以加群。
如果沒(méi)有工作經(jīng)驗(yàn),但基礎(chǔ)非常扎實(shí),對(duì)java工作機(jī)制,常用設(shè)計(jì)思想,常用java開發(fā)框架掌握熟練的可以加群。