整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Jersey with SpringBoot

          Jersey with SpringBoot

          ttps://www.tony-bro.com/posts/890461404/

          前言

          恰巧有機會用到Jersey這個RESTful Webservice框架,項目看起來比較老舊,有點臟亂差,遂整合到SpringBoot上,并且同時配上Swagger作為API文檔解決方案。從完全不了解Jersey到整合完成耗時并不長,總得來說還是非常方便的。

          Jersey入門

          說起來Java總是一堆規范,這回也不例外,Jersey同樣是JAX-RS規范的標準開源實現。JAX-RS即Java API for RESTful Web Services,屬于Java EE6的一部分,現如今已經發展到2.1版本(JSR311、JSR370)。本篇不討論Jersey本身的實現,因此大部分的應用情景使用的就是JAX-RS的接口和注解。

          如今web中的概念頗多,MVC、WebServie、SOA、微服務等等,尤為理不清的就是這WebService,在UDDI、WSDL(WADL)的概念下迷失。但是刨開有的沒的,說到底就是Request和Response,在如今前后端分離的情境下MVC的V基本被砍光,剩下的MC和除去自描述的WebService在應用接口的開發上個人認為已經極其相似,使用的時候也可以發現兩者形式也基本一樣。那么用慣了SpringMVC后,學習使用Jersey并不會有什么障礙,縱觀發展可以發現SpringMVC在完善支持返回json結構體,而Jersey現如今也支持MVC模板,殊途同歸。

          Jersey目前也是兩個大版本1.x和2.x,2.x也不是什么新鮮事物了,因此就以2.x為準。關于Jersey的入門推薦參看https://www.jianshu.com/nb/21274943這里面的幾篇文章,講的算比較不錯了。本篇就相當于濃縮再濃縮,詳細了解還是參考官方文檔最為穩妥。

          關鍵概念

          • Jersey是一個REST框架,是JAX-RS規范的標準開源實現
          • 基于Jersey的應用可以不依賴Servlet環境,可以在Servlet容器中使用,也可以在Http容器中使用
          • 不僅僅是Server端,JAX-RS也提供了客戶端API,客戶端也可以不準確的描述為請求發送器。Jersey通過擴展機制交由其他工具來實現這些內容,如JDK、grizzly、apache http等等。
          • 對于組件(資源映射類等),默認情況下Jersey將為每次請求創建一個新的對象(與Struts相似)。

          資源映射

          在RESTful WebService中,資源是核心,整個應用圍繞資源的映射和處理。與WebMVC所對應的便是請求的映射即RequestMapping,兩者只是解釋的入口點不同。對應的示例代碼如下:

          // Spring MVC
          @RequestMapping(value="/comments" ,method=RequestMethod.GET)
          @ResponseBody
          public JsonResult getComments(@RequestParam(value="articleid") Long articleid,
                                        @RequestParam(value="pn",defaultValue="1") Integer pn){
                  // some implementation
          }
          
          // JAX-RS
          @Path("/comments")
          @GET
          @Produces(MediaType.APPLICATION_JSON)
          public JsonResult getComments(@QueryParam(value="articleid") Long articleid,
                                        @QueryParam("pn") @DefaultValue("1") Integer pn){
                  // some implementation
          }

          簡單列一下主要注解:

          JAX-RS

          描述

          SpringMVC

          @Path

          配置路徑,可以置于類和方法上

          @RequestMapping

          @PathParam

          路徑變量的獲取,@Path指定的路徑同樣可以配置{param}

          @PathVariable

          @GET、@POST等

          描述請求方法,相同功能的還有@HttpMethod

          @GetMapping等

          @CookieParam、@FormParam等

          快速綁定不同類型的參數


          @DefaultValue

          參數的默認值

          @RequestParam(default="…")

          @Consumes、@Produces

          定義Http接收、返回類型


          對于表單請求,Jersey額外提供了@BeanParam注解,可以將@FormParam注解在Bean的屬性上,然后直接使用@BeanParam接收參數。也可以直接通過MultiValuedMap<String, String>來接收參數。

          相對特殊的@MatrixParam可以用于接收/resource;pageSize=10;currentPage=2`這個請求中的pageSize和currentPage,這樣使用的意圖是將每一個分頁看做一個資源,分頁信息不是參數而是資源的一部分。

          應用配置

          JAX-RS中提供了應用類javax.ws.rs.core.Application,定義了應用的基本組件信息,為了方便配置,Jersey提供了一系列繼承了Application的ResourceConfig類,可以使用此類來快速配置。如果需要配置Jersey的根路徑,在Servlet3.0以上的環境下可以使用注解@ApplicationPath("BasePath")注解在配置類上。

          信息轉換

          任何Web框架都會涉及信息的轉換,用于將請求信息轉換成可編程的對象,例如SpringMVC的MessageConverter。在JAX-RS中定義了兩個接口:MessageBodyWriter和MessageBodyReader,通過實現這兩個接口來處理輸入輸出的轉換,查看繼承關系可以看到Jersey默認提供的一些轉換器。

          過濾攔截

          JAX-RS定義了兩個面向切面的工具Filter和Interceptor,注意這個Filter和Servlet的Filter并不相同,行為上也不一樣,JAX-RS規范下的Filter和Interceptor都是單向的,請求歸請求,響應歸響應。過濾器一般用來處理頭部信息且分為客戶端過濾器和服務端過濾器,服務端核心接口為ContainerRequestFilter和ContainerResponseFilter;而攔截器主要用于修改實體的內容,比如編碼解碼等,核心接口為WriterInterceptor和ReaderInterceptor。

          需要注意如果請求不存在的地址,則RequestFilter不會執行,而只要有響應ResponseFilter就會執行,這實際上涉及到Filter的匹配時機,匹配時機分為PreMatch和PostMatch,默認為PostMatch。整個請求在服務端的執行順序如下:

          1. 收到請求
          2. 標記PreMatch的ContainerRequestFilter執行,并完成方法映射
          3. 標記PostMatch的ContainerRequestFilter執行
          4. ReaderInterceptor執行
          5. MessageBodyReader執行
          6. 具體資源方法執行
          7. ContainerResponseFilters執行
          8. WriterInterceptor執行
          9. MessageBodyWriter執行
          10. 返回響應

          輔助對象

          支持使用注解@Context注入一些特定的Web對象來輔助處理,包括:

          1. UriInfo:封裝了每次請求的相關信息
          2. HttpHeader:請求頭信息
          3. Request:輔助類,并非請求本身
          4. ServletContext、ServletRequest、ServletResponse

          可以置于方法參數上,也可以置于類成員上,同樣是通過動態代理來實現。

          上傳下載

          為支持上傳和下載需要引入jersey-media-multipart包,并且在配置類中注冊MultiPartFeature。

          上傳時可以使用@FormDataParam,可注解在InputStream和FormDataContentDisposition上,用于獲取文件數據和文件描述。

          下載時可以使用javax.ws.rs.core.Response直接攜帶文件構建出適合的響應。

          // 上傳
          @POST
          @Path("image1")
          @Produces(MediaType.APPLICATION_JSON)
          @Consumes(MediaType.MULTIPART_FORM_DATA)
          public String upload(@FormDataParam("file") InputStream fileInputStream,
                  @FormDataParam("file") FormDataContentDisposition disposition) {
          
              File upload=new File(ctx.getRealPath("/upload"), disposition.getFileName());
              try {
                  // handle input stream...
              } catch (IOException e) {
                  e.printStackTrace();
              }
              return "success";
          }
          
          // 下載
          @GET
          @Path("/images2/{name}")
          public Response showImg(@PathParam("name") String imageName) throws IOException {
              File f ;
              // find and get file...
              if (!f.exists()) {
                  return Response.status(Status.NOT_FOUND).build();
              } else {
                  return Response.ok(f).header("Content-disposition", "attachment;filename=" + imageName)
                          .header("Cache-Control", "no-cache").build();
              }
          }

          異常處理

          JAX-RS提供了一個標準的異常類WebApplicationException(繼承RuntimeException)可以在資源方法、provider、StreamingOutput中拋出這個異常讓Jersey統一處理。WebApplicationException有很多構造方法來滿足指定異常信息,但是在實際使用過程中比較難滿足定制的需求。

          此外還提供了ExceptionMapper接口,該接口只有一個方法:Response toResponse(E exception)即針對指定類型的異常如何生成Response對象,這樣就完成了異常類型和返回對象的映射。

          @Provider
          public class ErrorHandler implements ExceptionMapper<Exception> {
          
              @Override
              public Response toResponse(Exception exception) {
                  return Response.status(Response.Status.INTERNAL_SERVER_ERROR)
                          .entity(ResponseEntity.status(500).body(exception.getMessage()+"-"+this))
                          .type(MediaType.APPLICATION_JSON)
                          .build();
              }
          }

          整合SpringBoot

          整合Spring

          自Jersey2.x以來,Jersey的DI(依賴注入)默認由HK2這個符合J2EE標準的框架來實現。如果要整合SpringBoot,首先需要整合Spring容器。這一步同樣已經提供好了解決方案,引入jersey-spring包即可,本質上是由HK2提供的Spring-Bridge來完成轉換的。

          整合Spring后,值得注意的是Jersey本身會掃包,但為了讓Spring來管理相關的組件仍然需要在組件上增加注解@Component(純注解配置模式)。此外在Spring管理下組件的默認行為變為單例。

          Boot自動配置

          SpringBoot官方提供了Jersey的自動配置類JerseyAutoConfiguration和依賴包spring-boot-starter-jersey。注意只需要引入spring-boot-starter-jersey而不需要再額外引入spring-boot-starter-web,Jersey和SpringMVC不需要同時存在,spring-boot-starter-jersey已經引入了足夠的依賴項來啟動一個基本的應用服務。

          可以看到額外包含了Json序列化和參數校驗特性。

          JerseyAutoConfiguration這自動配置類中的內容也很簡潔,主要包含3個部分:

          • 構造函數,包括3個參數:JerseyProperties、ResourceConfig、ResourceConfigCustomizer(接口),用于項目的定制
          • FilterRegistrationBean和ServletRegistrationBean,說明整合SpringBoot時,Jersey的入口是Servlet(默認)或者Filter
          • 定制化的Json序列化組件,通過Jackson來實現,注冊JAX-RS組件、適配JAXB。

          搭建完工程后,可以選擇直接定制注入一個ResourceConfig,也可以讓組件實現ResourceConfigCustomizer來分散配置。

          Jersey獲取組件是通過掃包或者手動注冊,SpringBoot有額外提醒不推薦使用Jersey的掃包功能,因為在war包環境下有可能出現掃包失敗,詳見原文地址。

          然后整合就基本上完成了,可配的屬性不是特別多,主要包括選擇filter還是servlet、servlet啟動時加載(load-on-startup)、以及初始化參數init。

          整合Swagger和Swagger-UI

          雖然說WebService有自描述的功能,可以配合客戶端來使用WSDL、WADL,但是可讀性不好,如果是用來編寫應用的接口,就更加額外需要編寫相關的接口文檔。Swagger的動態特性非常不錯,同時對RESTful風格的接口支持尤其出色,因此使用它作為接口文檔解決方案。

          配置Swagger

          不同于與SpringMVC整合時有方便的spring-fox來便捷處理,與Jersey整合時需要額外進行一些操作,但也不麻煩。目前Swagger已經發展到3系列,不過應用還不是特別廣,所以仍選用了swagger2。引入依賴:

          <dependency>
              <groupId>io.swagger</groupId>
              <artifactId>swagger-jersey-jaxrs</artifactId>
              <version>1.5.22</version>
          </dependency>

          然后在Jersey的配置類中注冊swagger組件,并且定制swagger內容

          @Component
          @ApplicationPath("your_base_path")
          public class JerseyConfig extends ResourceConfig {
          
              public JerseyConfig() {
                  this.packages("com.demo.jerseyboot");
          
                  this.register(MultiPartFeature.class);
          
                  this.property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
          
                  this.configureSwagger();
              }
          
              private void configureSwagger(){
                  // 注冊兩個JAX-RS組件
                  this.register(ApiListingResource.class);
                  this.register(SwaggerSerializers.class);
          
                  // swagger定制
                  BeanConfig config=new BeanConfig();
                  config.setConfigId("數據服務接口文檔");
                  config.setTitle("數據服務接口文檔");
                  config.setVersion("v1");
                  config.setContact("tony");
                  config.setSchemes(new String[] { "http" });
                  config.setBasePath("your_base_path");
                  config.setResourcePackage("com.demo.jerseyboot");
                  config.setPrettyPrint(true);
                  config.setScan(true);
              }
          }

          查看ApiListingResource這個類,可以看到swagger注冊了一個接口,請求/swagger.json或者/swagger.yaml就可以獲取到API文檔的信息數據。

          可以看到真正起作用的是swagger-jaxrs包下的內容,因此如果需要使用swagger3,引入swagger-jaxrs2即可。

          配置Swagger-UI

          擁有文檔信息后還需要使用Swagger-UI來進行可視化展現。為了方便,采用webjars技術來引入相關的靜態網頁資源。引入依賴:

          <dependency>
              <groupId>org.webjars</groupId>
              <artifactId>swagger-ui</artifactId>
              <version>3.22.0</version>
          </dependency>

          在這個jar包內包含了Swagger-UI網頁的各種資源,查看index.html可以發現其中調用獲取接口信息的地址默認是https://petstore.swagger.io/v2/swagger.json,因此需要將其拷貝出來復制在類路徑下,修改其中靜態資源的引用路徑和接口信息的路徑。

          此時就需要處理靜態資源的訪問,由于不使用SpringMVC,那么也就沒辦法直接使用其提供的ResourceHttpRequestHandler,需要額外配置Web容器的靜態資源訪問。首先配置Jersey的根路徑,不要配置為/防止沖突,然后配置容器或者Servlet。

          對于webjars資源的訪問,SpringBoot已經做了默認配置,獲取webjar資源路徑的方法位于org.springframework.boot.web.servlet.server.AbstractServletWebServerFactory#getUrlsOfJarsWithMetaInfResources,查看AbstractServletWebServerFactory的子類中使用該方法的位置就可以看到對webjars資源的配置操作。

          Jetty容器

          如果使用Jetty作為容器,那么可以選擇使用Jetty提供的ResourceHandler

          @Component
          public class JettyResourceCustomizer implements WebServerFactoryCustomizer<ConfigurableJettyWebServerFactory>, Ordered {
          
              @Override
              public void customize(ConfigurableJettyWebServerFactory factory) {
                  factory.addServerCustomizers(new JettyServerCustomizer() {
                      @Override
                      public void customize(Server server) {
                          ResourceHandler staticHandler=new ResourceHandler();
                          staticHandler.setDirectoriesListed(true);
                          staticHandler.setWelcomeFiles(new String[]{"index.html"});
          
                          ContextHandler context0=new ContextHandler();
                          context0.setContextPath("/api-doc");
                          context0.setBaseResource(Resource.newClassPathResource("static"));
                          context0.setHandler(staticHandler);
          
                          // 注意不要覆蓋原有的Handler
                          Handler[] handlers=server.getHandlers();
                          Handler[] newHandlers=Arrays.copyOf(handlers, handlers.length + 1);
                          newHandlers[handlers.length]=context0;
          
                          ContextHandlerCollection contexts=new ContextHandlerCollection();
                          contexts.setHandlers(newHandlers);
          
                          server.setHandler(contexts);
                      }
                  });
              }
          
              @Override
              public int getOrder() {
                  // 確保在原生handler配置之后執行
                  return 100;
              }
          }

          Tomcat容器

          如果使用嵌入式Tomcat容器,則會稍微麻煩一些,嵌入式Tomcat的文檔很少,最后參看SpringBoot對Webjars資源的配置找到了解決方案

          @Component
          public class TomcatStaticResourceCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {
          
              @Override
              public void customize(TomcatServletWebServerFactory factory) {
                  factory.addContextCustomizers(new TomcatContextCustomizer() {
                      @Override
                      public void customize(Context context) {
                          WebResourceRoot root=context.getResources();
                          // 此時資源root為null
                          System.out.println(root);
          
                          // 使用tomcat的listener進行配置
                          context.addLifecycleListener(new LifecycleListener() {
                              @Override
                              public void lifecycleEvent(LifecycleEvent event) {
                                  if (event.getType().equals(Lifecycle.CONFIGURE_START_EVENT)) {
                                      context.getResources().createWebResourceSet(
                                              WebResourceRoot.ResourceSetType.PRE,"/api-doc", this.getClass().getResource("/"),"/static"
                                      );
                                  }
                              }
                          });
                      }
                  });
              }
          }

          樣例

          例如將index.html拷貝至如下的位置,并且配置Jersey的根路徑為/api

          修改其中的內容

          <!-- HTML for static distribution bundle build -->
          <!DOCTYPE html>
          <html lang="en">
            <head>
              <meta charset="UTF-8">
              <title>Swagger UI</title>
              <link rel="stylesheet" type="text/css" href="../webjars/swagger-ui/3.22.0/swagger-ui.css" >
              <link rel="icon" type="image/png" href="../webjars/swagger-ui/3.22.0/favicon-32x32.png" sizes="32x32" />
              <link rel="icon" type="image/png" href="../webjars/swagger-ui/3.22.0/favicon-16x16.png" sizes="16x16" />
              <style>
                html
                {
                  box-sizing: border-box;
                  overflow: -moz-scrollbars-vertical;
                  overflow-y: scroll;
                }
          
                *,
                *:before,
                *:after
                {
                  box-sizing: inherit;
                }
          
                body
                {
                  margin:0;
                  background: #fafafa;
                }
              </style>
            </head>
          
            <body>
              <div id="swagger-ui"></div>
          
              <script src="../webjars/swagger-ui/3.22.0/swagger-ui-bundle.js"> </script>
              <script src="../webjars/swagger-ui/3.22.0/swagger-ui-standalone-preset.js"> </script>
              <script>
              window.onload=function() {
                // Begin Swagger UI call region
                const ui=SwaggerUIBundle({
                  url: "../api/swagger.json",
                  dom_id: '#swagger-ui',
                  deepLinking: true,
                  presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset
                  ],
                  plugins: [
                    SwaggerUIBundle.plugins.DownloadUrl
                  ],
                  layout: "StandaloneLayout"
                })
                // End Swagger UI call region
          
                window.ui=ui
              }
            </script>
            </body>
          </html>
          
          

          訪問host:port/api-doc/index.html就可以看到自動生成的API文檔。

          總結

          說實話Jersey來整合SpringBoot個人感覺意義并不是特別大,SpringBoot講求一個便捷快速,Jersey本身同樣也很輕巧,且SpringMVC擺在這里,頗有些食之無味,棄之可惜的感覺。整合SpringBoot后最大的好處還是IOC、AOP以及Spring生態的支持以及其他工具的快速整合,由此可見生態的重要性。

          總體來說JAX-RS這套API挺不錯的,該有的都有,對比SpringMVC可以發現Web開發的共同之處,確有裨益。

          pring Boot Web容器

          Web應用開發是企業開發的重要領域,Spring Boot 1.X的Web容器管理方式基于Servlet容器技術棧。Servlet容器主要基于同步阻塞I/O架構,HTTP請求和線程是一對一的關系,主要是TPR模型,即一個請求對應一個線程。主要的業務邏輯也是基于命令式的編程模式。以Spring MVC框架為主,Web容器方面以Tomcat為主,也可以通過自動配置功能改為Jetty/UnderTow容器。

          Spring Boot 2.X主要基于異步非阻塞I/O架構,HTTP請求基于收斂的線程模型,網絡層使用基于Reactor的I/O多路復用模式,業務邏輯基于函數式編程模式,以Spring WebFlux為主要框架。在Web容器方面可以基于Servlet 3.0的異步模式,默認情況下使用Netty作為容器。本節我們主要以Spring Boot 1.X講解嵌入式Web容器的啟動和加載原理,在進階篇的響應式編程中將介紹Spring 5及Spring Boot 2.X的響應式框架WebFlux對Web應用服務的支持。

          Spring Boot Web容器配置

          Spring Boot對Web項目的支持主要是Spring Boot對Spring MVC框架的繼承。Spring MVC框架是一個基于Servlet容器標準的Web容器框架實現,Spring Boot向Spring MVC提供開箱即用的Starter:springboot-starter-web。

          Spring Boot應用中利用自動配置功能,只需要在pom.xml文件中加入下面的Web依賴,就可以直接啟動一個Web服務:

          Spring Web MVC 框 架 使 用 特 定 的 @Controller 或 者@RestController 注 解 的 Bean 作 為 處 理 HTTP 請 求 的 端 點 , 通 過@RequestMapping注解將控制器中的方法與HTTP請求進行映射,示例如下:

          Spring Boot為Spring MVC提供了自動配置功能,包含如下主要配置特性。

          ● 自動配置ViewResolver引入ContentNegotiatingViewResolver組件功能。示例:在應用中添加ViewResolver組件用來匹配HTML靜態頁面,如果沒有匹配成功,則返回false,由其他ViewResolver繼續嘗試匹配。ContentNegotiatingViewResolver會組合所有的視圖解析器,代碼如下。

          ● 自動注冊Converter、GenericConverter、Formatter Bean。

          示例:將頁面提交數據轉化為后臺數據,實現格式化,代碼如下。

          ● 對HttpMessageConverters的支持。

          示例:Spring Boot可以為HttpMessageConverters類添加自定義轉換類,通過這種方式可以將所有的HttpMessageConverters的Bean添加到Converter列表,覆蓋默認的轉換器列表,代碼如下。

          ● 自動注冊MessageCodeResolver。

          ● 自動使用ConfigurableWebBindingInitializer Bean。

          ● 使用WebMvcConfigurerAdapter類型的Bean來定制化配置。

          默認情況下,Spring Boot會以/src/main/resources/static作為查找靜態資源的文件路徑,如果想自定義靜態資源映射目錄,需要重寫addResourceHandlers來添加指定路徑,重寫addResourceLocations來指定靜態資源路徑。

          總之,我們可以根據自己的意愿,對默認的Spring MVC的組件配置加以修改,方法也很簡單,通過在IoC容器中注冊新的同類型Bean來替換即可。如果你希望完全接管Spring MVC的所有相關配置,可以添加自己的@Configuration,并使用@EnableWebMvc注解實現定制化配置。

          JAX-RS和Jersey框架

          如果你喜歡JAX-RS和REST風格的編程模型,可以使用下面的Starter替代Spring MVC框架,Spring支持Jersey 1.X和Jersey 2.X等技術框架。這里我們只介紹Spring Boot對Jersey 2.X的支持,在pom.xml文件中加入下面的依賴:

          Spring Boot對Jersey的配置有三種主要方式。在開始不同的配置方式前,我們注冊一個端點對象資源,示例代碼如下:

          ● 第一種方式,創建一個自定義的ResourceConfig:

          ● 第二種方式,返回一個ResourceConfig類型的@Bean:

          ● 第三種方式,配置一組ResourceConfigCustomizer對象。

          Spring Boot提供了ResourceConfigCustomizer接口,讓我們更靈活地對ResourceConfig對象進行配置。要使用該接口,我們需要先注釋掉前面兩節中提到的相關代碼,然后創建一個類:

          默 認 情 況 下 , Jersey 將 以 Servlet 的 形 式 注 冊 一 個

          ServletRegistrationBean 類 型 的 @Bean 。 它 的 名 字 為

          jerseyServletRegistration,該Servlet默認會延遲初始化。

          你可以通過spring.jersey.servlet.load-on-startup自定義配置

          Jersey組件。通過創建相同名字的Bean,可以禁用或覆蓋框架默認的

          Bean。設置spring.jersey.type=filter可以使用Filter的形式代替

          Servlet , 相 應 的 @Bean 類 型 變 為 jerseyFilter-Registration , 該

          Filter有一個@Order屬性,你可以通過spring.jersey.filter.order

          設 置 該 屬 性 。 Servlet 和 Filter 在 注 冊 時 都 可 以 使 用

          spring.jersey.init.*定義一個屬性集合并將其傳遞給init參數進行

          初始化。

          內嵌容器的配置

          Spring Boot 的 另 一 大 特 性 就 是 支 持 內 嵌 的 Web 容 器 , 包 括Tomcat、Jetty和UnderTow服務器,大多數開發者只需要使用合適的Starter來獲取一個完全配置好的實例即可,內嵌服務器默認監聽8080端口的HTTP請求。spring-boot-starter-web默認使用Tomcat作為Web容器,你可以在pom.xml中去除spring-boot-starter-tomcat依賴,然后 引 入 spring-boot-starter-jetty 或 者 spring-boot-starterundertow模塊作為替代Web容器方案。Starter還提供了以“server.”為前綴的配置項對嵌入式容器配置進行修改。配置項的加載和定制化鉤子加載過程如下。

          1.自動化配置嵌入式容器

          2.初始化TomcatEmbeddedServletContainerFactory的Bean對象

          3.定制化Bean擴展邏輯

          EmbeddedServletContainerCustomizerBeanPostProcessor在加載Bean后開始初始化配置項PostProcessor的處理邏輯:

          4.配置文件加載

          從配置文件中,你可以加載配置文件對象的配置值。如果配置文件中沒有相關配置項,將使用默認代碼設定配置。

          5.Web容器定制化

          如果你需要對Web容器進行更深入的定制,可以使用對應的Factory自動化配置Tomcat容器,它是初始化的關鍵流程和步驟,代碼示例如下:

          下圖是Spring Boot啟動過程中Tomcat容器完成自動配置的類圖結構。我們在最新的Spring Boot下查看Tomcat的相關配置,發現有兩個自動裝配類,分別包含了三個定制器,還有一個工廠類。

          本文給大家講解的內容是SpringBootWeb容器配置:JAX-RS和Jersey框架、內嵌容器的配置

          1. 下篇文章給大家講解的是Spring Boot嵌入式Web容器原理
          2. 覺得文章不錯的朋友可以轉發此文關注小編;
          3. 感謝大家的支持!
          1. aven swagger依賴:

          主站蜘蛛池模板: 日本在线观看一区二区三区| 九九久久99综合一区二区| 无码人妻精品一区二区三区蜜桃| 久久精品一区二区国产| 亚洲码欧美码一区二区三区| 中文字幕一区二区三区精华液| 亚洲美女一区二区三区| 91一区二区三区| 国产丝袜无码一区二区视频| 男插女高潮一区二区| 亚洲福利一区二区三区| 亚洲国产精品一区第二页| 区三区激情福利综合中文字幕在线一区亚洲视频1 | 人妻夜夜爽天天爽一区| 亚洲国产精品乱码一区二区| 国产精品小黄鸭一区二区三区| 无码人妻aⅴ一区二区三区有奶水 人妻夜夜爽天天爽一区 | 国产成人无码AV一区二区| 亚洲片国产一区一级在线观看 | 人妻无码第一区二区三区| 国产一区二区在线看| 精品乱码一区内射人妻无码| 国产成人一区二区三区| 国产成人精品一区二三区熟女| 亚洲欧美成人一区二区三区 | 无码日韩人妻AV一区二区三区 | 97久久精品一区二区三区| 日韩高清国产一区在线 | 亚洲日韩AV一区二区三区中文| 亚洲AV成人一区二区三区AV| 国产成人无码AV一区二区| 制服中文字幕一区二区| 中文字幕乱码一区二区免费| 国产精品日本一区二区在线播放 | 日本大香伊一区二区三区| 国产AV午夜精品一区二区入口| 性色AV一区二区三区| 国产精品自拍一区| 日韩在线观看一区二区三区| 日韩一区二区三区精品| 中文字幕一精品亚洲无线一区|