SpringBoot嵌入式容器詳細介紹
概述
Spring Boot支持嵌入式Tomcat、Jetty和Undertow服務器。大多數開發人員使用適當的 “starter”來獲得完全配置的實例。默認情況下,嵌入式服務器在端口8080上監聽HTTP請求。
默認引入下面依賴使用Tomcat服務器。
如需要使用其它如Undertow作為服務器只需要如下依賴即可。
Servlets, Filters, and listeners
當使用嵌入式servlet容器時,可以通過使用Spring bean或掃描servlet組件來注冊servlet、filter和servlet規范中的所有監聽器(如HttpSessionListener)。
Registering Servlets, Filters, and Listeners as Spring Beans
任何Spring bean的Servlet、Filter或 *Listener實例都注冊到嵌入式容器中。如果你想從應用程序中引用一個值,這可能特別方便。配置過程中的屬性。
默認情況下,如果上下文只包含單個Servlet,則將其映射到/。在有多個servlet bean的情況下,bean名用作路徑前綴。Filter映射到/*。
如果基于約定的映射不夠靈活,可以使用ServletRegistrationBean、FilterRegistrationBean和ServletListenerRegistrationBean類進行完全控制。
通常情況下,將Filter Bean放置無序是安全的。如果需要特定的順序,則應該使用@Order注釋過濾器,或者讓它實現Ordered。你不能通過給過濾器的bean方法加上@Order注解來配置它的順序。如果不能更改過濾器類以添加@Order或實現Ordered,則必須為過濾器定義一個FilterRegistrationBean,并使用setOrder(int)方法設置注冊bean的訂單。避免配置按順序讀取請求體的過濾器。
注:要查看應用程序中每個過濾器的順序,請為web日志組啟用調試級別日志(logging.level.web=debug)。注冊過濾器的詳細信息,包括它們的順序和URL模式,將在啟動時記錄下來。
Servlet Context Initialization
嵌入式servlet容器不會直接執行servlet 3.0+javax.servlet.ServletContainerInitializer接口或Spring的org.springframework.web.WebApplicationInitializer接口。這樣做是有意為之,目的是降低在war中運行的第三方庫破壞Spring Boot應用程序的風險。
如果需要在Spring Boot應用程序中執行servlet上下文初始化,應該注冊一個實現org.springframework.boot.web.servlet.ServletContextInitializer接口的bean。單一的onStartup方法提供了對ServletContext的訪問,如果有必要,可以很容易地將其用作現有WebApplicationInitializer的適配器。
掃描 Servlets, Filters, and listeners。
在使用嵌入式容器時,可以通過使用@ServletComponentScan?來啟用自動注冊帶有@WebServlet、@WebFilter和@WebListener注解的類。
容器之ServletWebServerApplicationContext
在底層,Spring Boot使用了另一種類型的ApplicationContext來支持嵌入式servlet容器。ServletWebServerApplicationContext是一種特殊類型的WebApplicationContext,它通過搜索單個ServletWebServerFactory bean來引導自己。通常TomcatServletWebServerFactory、JetttyServletWebServerFactory或UndertowServletWebServerFactory都是自動配置的。
你通常不需要知道這些實現類。大多數應用程序都是自動配置的,并且創建適當的 ApplicationContext和ServletWebServerFactory。
在嵌入式容器設置中,ServletContext被設置為服務器啟動的一部分,該啟動發生在應用程序上下文初始化期間。因此,ApplicationContext中的bean不能可靠地用ServletContext進行初始化。解決這個問題的一種方法是注入ApplicationContext作為bean的依賴項,并僅在需要時訪問ServletContext。另一種方法是在服務器啟動后使用回調函數。這可以使用ApplicationListener來監聽ApplicationStartedEvent,如下所示:
自定義Servlet容器
可以使用Spring環境屬性來配置公共servlet容器設置。application.properties或application.yaml文件。
常見的服務器設置包括:
- 網絡設置:監聽傳入的HTTP請求的端口(server.port),綁定到server.address。地址,等等。
- Session設置:會話是否持久(server.servlet.session.persistent),會話超時(server.servlet.session.timeout),會話數據的位置(server.servlet.session.store-dir),以及會話cookie配置(server.servlet.session.cookie.*)。
- 錯誤管理:錯誤頁面的位置(server.error.path)等。
- SSL
- HTTP compression
編程方式自定義配置
如果需要以編程方式配置嵌入式servlet容器,可以注冊一個實現WebServerFactoryCustomizer接口的Spring bean。WebServerFactoryCustomizer提供了對ConfigurableServletWebServerFactory的訪問,其中包括許多自定義設置方法。示例:
TomcatServletWebServerFactory,JetttyServletWebServerFactory和UndertowServletWebServerFactory是ConfigurableServletWebServerFactory的子類,它們分別為Tomcat, Jetty和Undertow提供了額外的自定義設置方法。示例:
JSP限制
當運行一個使用嵌入式servlet容器的Spring Boot應用程序(打包為可執行的歸檔文件)時,對JSP的支持有一些限制。
- 使用Jetty和Tomcat,如果你使用war打包,它應該可以正常工作。當使用java -jar啟動時,不支持jsp。
- Undertow不支持jsp。
- 創建自定義error.jsp頁面不會覆蓋錯誤處理的默認視圖。應該使用自定義錯誤頁面。