本文來自網易雲社區html
做者:李哲前端
2、Swagger-springmvc原理解析android
上面介紹瞭如何將springmvc和springboot與swagger結合,經過簡單配置生成接口文檔,以及介紹了swagger提供的一些註解。下面將介紹swagger是如何作到與springmvc結合,自動生成接口文檔。git
項目添加完成maven依賴後會加入swagger的依賴包,其中包括swagger- springmvc,swagger-annotations,swagger-models幾個依賴包。以下圖所示:github
其中,swagger-annotations是swagger提供給spring的註解包,上面說的註解基本都在這個包裏面;swagger-models是swagger本身的model類,主要用於將註解解析成後面須要使用的model和一些model數據的處理。Swagger-springmvc是swagger接入spring的一個最重要的包,經過這個包的處理能夠將添加的註解信息解析出來,自動生成接口須要的數據,最後經過url請求就能返回接口的信息,經過前端處理就能夠在頁面上看到接口的信息。下面將重點分析swagger-springmvc包下的文件,本文中分析的是1.0.2版本的swagger-springmvc,其餘版本會存在差別,請自行研究。spring
下圖是swagger-springmvc包結構,圖中標紅的兩個類是swagger的入口類,根據包的名字大體能猜出各個模塊的功能。這裏先簡單介紹下,annotation包下只有一個註解類ApiIgnore,用於忽略不被swagger處理;authorization包下主要用於處理須要認證的接口,添加認證信息;configuration主要處理配置相關的操做,其中包含了程序的配置SpringSwaggerConfig類,該類是swagger的默認配置類,也能夠本身編寫封裝去修改配置(通常都會編寫本身的配置類,設置一些api信息等)。Controller用於處理請求swagger文檔時返回數據給前端ui;core是整個處理過程的核心模塊,例如註解的解析,model的處理,一些處理過程當中的策略等等;ordering包中是用於處理頁面顯示接口時,一些排序問題,其中的class都繼承了Ordering<T>類,實現了Comparator<T>接口;paths包下了類主要是處理前端訪問swagger接口時的路徑問題;plugin是swagger和spring結合的適配處理,也是程序的入口,相對spring來講,swagger就像一個插件接入spring中;scanners和readers兩個包主要是處理註解的獲取和掃描解析。swagger- springmvc包下的大體結構就是這樣的,看到這是否是以爲swagger沒那麼神奇了,其實swagger作的兩件最主要的事就是:掃描解析註解變成相應的model,前端請求接口文檔時返回後臺處理好的接口信息。編程
立刻就要進入程序入口了,是否是有點激動呢?可能有的人會問,怎麼知道Swagger PluginAdapter是程序的入口?配置的文件不是SpringSwaggerConfig嗎?進入源代碼就能找到答案,下面來看下SwaggerPluginAdapter類:api
這個類實現了ApplicationListener<ContextRefreshedEvent>接口,這是一個spring的接口,在spring的applicationcontext初始化完成後會執行onApplicationEvent方法,因此當spring啓動後,swagger就會被啓動。而SpringSwaggerConfig中使用了註解@configuration,會在spring啓動時進行swagger配置,在配置的時候會根據用戶自定義的配置進行設置,若是用戶沒有定義將用默認的配置。下面看下方法onApplicationEvent中的處理,以下圖所示,程序會先去判斷plugins是否存在,不存在直接使用默認的,若是配置中設置了plugin則使用配置中的SwaggerSpringMvcPlugin,最後都調用Swagger SpringMvcPlugin類的initialize方法。安全
SwaggerSpringMvcPlugin是swagger和spring框架核心的類。有好多可配置的屬性,而且提供了相應的get與set方法。 在該類中,初始化了SwaggerApiResourceListing類(用於掃描RequestMappingHandler方法)的屬性。 當調用initialize()方法的時候,調用的則是SwaggerApiResourceListing類的initialize()方法。springboot
在initialize方法中主要作了兩件重要的事,第一經過apiListingReferenceScanner掃描全部的spring請求路徑(RequestMapping),過濾沒在配置類中設置的include Patterns,將掃描結果轉換爲swagger自定義的model中。第二經過apiListingScanner類掃描第一步處理的每個請求路徑,根據swagger的註解掃描每個路徑對應的接口信息,最後將信息轉換爲swagger中model並保存在swaggerCache中方便之後使用。
接下來分析具體的掃描過程,ApiListingReferenceScanner中的scan方法是調用該類中的scanSpringRequestMappings方法。在該方法中主要作的是根據spring中的Request MappingHandlerMapping找出符合條件的路徑並找出一些須要的信息保存起來。
ApiListingScanner類中主要掃描每一個請求路徑的具體接口信息,具體的掃描過程是經過命令模式執行。代碼中的每一種reader對應一種具體要執行的命令操做,對全部的請求路徑(RequestMapping)分別獲取MediaType、接口描述、接口model等信息。其中,MediaTypeReader是解析請求的MediaType類型,ApiDescriptionReader是解析接口的信息,ApiModelReader是解析接口的model(即ApiModel標註的類)。解析完成後分別將這些信息保存起來。ApiDescriptionReader中主要處理了請求路徑,而後經過ApiOperationReader去處理真正的接口信息。execute方法中能夠看到分別去處理寫在接口上的註解。
下面以一個OperationImplicitParametersReader爲例介紹各類Reader是如何經過命令模式去處理對應的註解,其中經過AnnotationUtils.findAnnotation方法去查詢Api ImplicitParams註解去獲取接口上標註的參數信息,而後在繼承類SwaggerParameterReader中的execute方法中被調用。
其餘的註解也是經過這種方式被讀取出來,最後會將這些信息保存到SwaggerCache中,到此swagger處理代碼中的註解就已完成,固然過程當中還有處理一些其餘信息,例如,須要登陸認證的信息,處理接口的請求路徑以方便swagger自己請求接口時應用等等。可是這些處理好的信息是怎麼能在前端頁面顯示的呢?接下來就研究下swagger如何在前端顯示接口信息。在swagger的默認配置類中有個ComponentScan註解標註須要掃描的包com.mangofactory.swagger.controllers,在該包下有一個controller叫DefaultSwaggerController,代碼以下:
能夠看到,swagger根據處理好的路徑對應返回相應的接口信息,從這裏能夠看到爲何解析的數據都放到SwaggerCache中,這樣後臺controller就能夠返回請求的接口數據,經過前端頁面的解析就能在前端顯示接口的信息。下圖是前端代碼結構,經過index.html訪問接口信息。
至此swagger-springmvc是如何作到經過簡單註解配置就能實現自動生成接口文檔信息的原理就講完了,具體細節處理有興趣者能夠本身研究。如今看來swagger也沒這麼神奇了,可是其中用到的方法是值得咱們學習使用的。例如,如何經過spring的方式獲取spring中管理的一些資源,命令模式,結合spring的插件開發等等。
3、Swagger其餘功能
除了上面介紹的功能外,swagger還有一些其餘功能,打開swagger的官網
https://swagger.io/能夠看到除了介紹的功能,還有一些其餘工具。
這裏簡單介紹下swagger包含的其餘功能,SwaggerEditor是一個swagger文檔編輯工具,經過該工具能夠實現靜態接口文檔編寫,並且能夠查看實時接口信息,上面一排按鈕能夠實現保存,生成相關代碼等功能。以下圖所示:
SwaggerCodeGen是一個代碼生成的工具,即經過該工具能夠實現根據接口信息生成各類語言的接口代碼,能夠生產前端、後臺、移動端代碼框架,能夠經過 swagger- codegen-cli腳手架工具或者訪問github地址:https://github.com/swagger-api/swagger- codegen根據提示操做,裏面也有示例。生成前端、移動端的代碼根據各語言通用的框架實現接口請求,例如android的代碼中使用okhttp請求接口數據;同時能夠經過靜態接口文檔生成服務器端代碼,這樣會根據文檔中定義的接口信息和model生成相應的model和controller接口。經過SwaggerCodeGen生成的代碼在大型項目中可能不太實用,由於裏面不少代碼不符合人們編碼習慣,可是在快速開發的小型項目中能夠嘗試使用。
Swagger UI是展現接口頁面的前端框架,接口信息就是經過這個框架顯示出來的,因此不論是靜態接口文檔仍是經過後臺代碼生成的接口信息均可以經過SwaggerUI來顯示。上面介紹的swagger結合springmvc使用中使用的就是Swagger UI來顯示接口頁面。下圖是swagger官網上的一個示例:
Swagger Inspector是一個測試接口工具,相似postman,主要用來測試請求返回狀況,能夠經過在線Swagger Inspector測試接口,基本測試是無償使用的。swagger還提供了一些高級功能,如安全掃描、複雜功能測試、load測試及監控數據等,能夠根據需求付費使用。以下圖所示,Swagger Inspector也能夠保存請求歷史,能夠選擇請求生成swagger文檔。
除此以外,swagger還提供了SwaggerHub,這是一個swagger倉庫,能夠將文檔上傳保存,同時支持團隊協做,在線編輯,安全線上查閱等功能。Swagger還提供不少開源項目和活躍的社區,若是遇到問題能夠去尋求幫助。
4、總結
本文主要介紹了swagger的簡介,如何在springmvc和springboot中使用swagger,swagger是如何在springmvc中發揮神奇功效的以及swagger的其餘功能等。可是swagger也存在一些問題,例如須要在後臺代碼中加一些註解,過多的註解形成註解氾濫;接口文檔須要等到後臺接口寫好才能在前端展現,而通常開發可能須要先定義好接口,而後纔開始寫代碼形成的流程混亂;要很深刻的瞭解swagger須要時間和精力,對於忙業務的開發可能以爲不值得在上面花時間學習。其實對於這些問題都有很好的辦法解決,相比經過簡單學習就能方便的得到接口信息並且不用反覆更新文檔是很值得的一件事。對於接口文檔須要等後臺開發完才能展現的問題,能夠先經過靜態的文檔書寫方式先寫文檔,以後再經過後臺接口方式實現。
經過上面的介紹,咱們瞭解到swagger是一個功能很是強大的工具,若是能很好地利用這個工具將很大程度上提升咱們的開發效率。雖然swagger以前也被爆出安全性問題,但這個問題在後續版本中獲得了修復,因此趕快學習使用這個神器。因爲時間倉促,若是文中有錯誤請諒解。
附(經常使用註解表):
相關閱讀:接口文檔神器Swagger(上篇)
網易雲大禮包:https://www.163yun.com/gift
本文來自網易雲社區,經做者李哲受權發佈
相關文章:
【推薦】 用SolrJ操做Solr作搜索(上篇)
【推薦】 【專家坐堂】四種併發編程模型簡介
【推薦】 視覺設計師的進化