熵增学院-Anders-剑走偏锋,了解Spring Boot内部Servlet容器
还记得大明湖畔的servlet吗?其实Spring Boot支持内嵌的Tomcat, Jetty和Undertow服务器,多数开发者只需要使用合适的'Starter'来获取一个完全配置好的实例即可,内嵌服务器默认监听8080端口的HTTP请求。
这样子是不是觉得很简单,很方便,有种开发nodejs的感觉.....
1. 在SpringBoot中还有Servlets, Filters和listeners吗?
使用内嵌servlet容器时,你可以通过使用Spring beans或扫描Servlet组件的方式注册Servlets,Filters及特定Servlet相关的所有listeners(比如HttpSessionListener
)。
将Servlets,Filters和listeners注册为Spring beans
所有Servlet
,Filter
或Servlet *Listener
实例,只要是Spring bean,都会注册到内嵌容器中。如果想在配置期间引用application.properties
的属性,这是非常方便的。默认情况下,如果上下文只包含单个Servlet,那它将被映射到/
。如果存在多个Servlet beans,那么bean的名称将被用作路径的前缀,过滤器将映射到/*
。
如果基于约定(convention-based)的映射不够灵活,你可以使用ServletRegistrationBean
,FilterRegistrationBean
,ServletListenerRegistrationBean
实现完全的控制。
1 创建servlet
package com.gala.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class TestServlet extends HttpServlet { private static final long serialVersionUID = -2646554587718007415L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置返回类型为json resp.setContentType("application/json"); // 设置返回字符集 resp.setCharacterEncoding("UTF-8"); // 输出对象 PrintWriter writer = resp.getWriter(); // 输出error消息 writer.write("成功执行doGet方法"); writer.close(); } }
2 使用Bean注册Servlet(单个Servlet)
package com.gala.servlet.conf; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import com.gala.servlet.TestServlet; @Configuration public class ServletConfiguration { @Bean public ServletRegistrationBean<TestServlet> servletRegistrationBean() { return new ServletRegistrationBean<TestServlet>(new TestServlet(), "/test"); } }
SpringBoot自动装配Servlet(多个Servlet)
SpringBoot内部提供了注解@ServletComponentScan,这个注解的作用就是自动扫描我们SpringBoot项目内的有关Servlet配置,自动装配到我们的项目中。
TestServlet需要与ServletConfiguration同目录或在其子目录中
修改ServletConfiguration,增加@ServletComponentScan
package com.gala.servlet.conf; import org.springframework.boot.web.servlet.ServletComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ServletComponentScan public class ServletConfiguration { }
修改TestServlet,增加@WebServlet(urlPatterns = "/test2")
package com.gala.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet(urlPatterns = "/test2") public class TestServlet extends HttpServlet { private static final long serialVersionUID = -2646554587718007415L; @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 设置返回类型为json resp.setContentType("application/json"); // 设置返回字符集 resp.setCharacterEncoding("UTF-8"); // 输出对象 PrintWriter writer = resp.getWriter(); // 输出error消息 writer.write("成功执行doGet方法"); writer.close(); } }
2. 在Filters和listeners怎么使用
内嵌servlet容器不会直接执行Servlet 3.0+的javax.servlet.ServletContainerInitializer接口,或Spring的org.springframework.web.WebApplicationInitializer接口,这样设计的目的是降低war包内运行的第三方库破坏Spring Boot应用的风险。
如果需要在Spring Boot应用中执行servlet上下文初始化,你需要注册一个实现org.springframework.boot.context.embedded.ServletContextInitializer接口的bean。onStartup方法可以获取ServletContext,如果需要的话可以轻松用来适配一个已存在的WebApplicationInitializer。
扫描Servlets, Filters和listeners
当使用一个内嵌容器时,通过@ServletComponentScan可以启用对注解@WebServlet,@WebFilter和@WebListener类的自动注册。
注 在独立的容器(非内嵌)中@ServletComponentScan不起作用,取为代之的是容器内建的discovery机制。
3. 自定义配置servlet容器
常见的Servlet容器配置可以通过Spring Environment进行设置,通常将这些属性定义到application.properties文件中。
常见的服务器配置包括:
网络设置:监听进入Http请求的端口(server.port),接口绑定地址server.address等。
Session设置:session是否持久化(server.session.persistence),session超时时间(server.session.timeout),session数据存放位置(server.session.store-dir),session-cookie配置(server.session.cookie.*)。
Error管理:错误页面的位置(server.error.path)等。
SSL。
HTTP压缩
Spring Boot会尽量暴露常用设置,但这并不总是可能的。对于不可能的情况,可以使用专用的命名空间提供server-specific配置(查看server.tomcat,server.undertow)。例如,可以根据内嵌servlet容器的特性对access logs进行不同的设置。
注 具体参考ServerProperties。
4. 老生常谈的JSP
当使用内嵌servlet容器运行Spring Boot应用时(并打包成一个可执行的存档archive),容器对JSP的支持有一些限制
Tomcat只支持war的打包方式,不支持可执行jar。
Jetty只支持war的打包方式。
Undertow不支持JSPs。
创建的自定义error.jsp页面不会覆盖默认的error handling视图。
- SpringBoot之在Servlet2.5容器中部署war应用
- Spring Boot 学习笔记(五) 配置Servlet容器
- spring boot下Servlet容器Tomcat和Undertow性能对比
- 170322、Spring Boot 性能优化之将Servlet容器变成Undertow
- 常规容器下SpringBootServletInitializer如何实现web.xml作用解析
- springboot框架servlet容器tomcat、Jetty、undertow压测报告
- 在部署到Servlet容器之前,如何生成包含SpringBoot的War文件
- springboot不同servlet容器benchmark
- 【spring-boot】spring-boot-配置嵌入式Servlet容器学习
- Spring实现原理分析(二十六).Spring Boot关于嵌入式servlet容器
- SpringBoot之配置嵌入式Servlet容器
- Spring Boot 内置与外置Servlet容器讲解(六)
- 常规容器下SpringBootServletInitializer如何实现web.xml作用解析
- 把spring-boot项目部署到tomcat容器中
- spring boot容器加载完后执行特定操作
- springboot设置默认容器为jetty
- SpringBoot15 之 Servlet
- 把spring-boot项目部署到tomcat容器中
- 新技术的了解-spring boot中提及
- jsp/servlet/struts/hibernate/spring内部实现机制