SpringBoot与servlet

  • Post author:
  • Post category:其他




一、servlet,servlet容器

Servlet 是一种基于 Java 技术的 Web 组件,用于生成动态内容,由容器管理。类似于其他 Java 技术组件,Servlet 是平台无关的 Java 类组成,并且由 Java Web 服务器加载执行。在以前的servlet规范中,必须放在相应的目录中才可以执行,比如web-inf,而SpringBoot就非常简单,不需要复杂的步骤。

Servlet容器,有时也称为Servlet引擎,作为Web服务器或应用服务器的一部分,通过请求和响应对话,提供Web客户端与Servlet交互的能力。容器管理Servlet实例以及他们的生命周期。

Servlet3.0以后,也就是tomcat8.0以后采用注解驱动。用注解或API的方式代替了XML,不需要XML就可以启动容器了。也就是说用jar包的方式就可以启动,不 需要用war包去启动了。SpringBoot用了嵌入式引擎,嵌入式引擎必须由嵌入式容器启动,tomcat之所以能做到嵌入式容器,是因为servlet做了改革。SpringBoot除了自动装配以外,还有一个最大的亮点是异步IO,异步上下文。Servlet3.1和websocket有紧密的关联。



二、servlet组件

1997年六月,Servlet 1.0 版本发行,当时还不属于J2EE规范,最新版本 Servlet 4.0 处于研发状态。下面说的都是servlet3.1规范,支持Tomcat8。Servlet 3.0 前时代,几乎都是注解驱动或API编程的方式。Annotation用于申明,真正的注册在于调用它 的API,通过API的方式动态的进行注册,之前只能通过XML配置,比较固态化。

常见服务组件

javax.servlet.Servlet

public interface Servlet {
    void init(ServletConfig var1) throws ServletException;

    ServletConfig getServletConfig();

    void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;

    String getServletInfo();

    void destroy();
}

javax.servlet.Filter(since Servlet 2.3)

Filter是在servlet之前执行的。

public interface Filter {
    void init(FilterConfig var1) throws ServletException;

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    void destroy();
}


上下文组件


javax.servlet.ServletContext

一个servlet容器是允许多个应用上下文的,SpringBoot里面至少有一个,实际上可以有两个应用上下文,一个是服务端,一个是管理端,一个应用上下文就是一个应用,一个Web容器里面可以支持多个应用的部署。

javax.servlet.http.HttpSession,

HTTPSession可以通过cookie或url重写的方式进行Session的跟踪,用于用户和服务端的识别,http是无状态的协议,session可以用来管理用户和服务端的会话。

javax.servlet.http.HttpServletRequest,请求上下文

javax.servlet.http.HttpServletResponse

javax.servlet.http.Cookie(客户端),存储信息量比session小

Cookie用于跟踪用户的会话,服务端发送一个cookie,相对于session来说,生命周期比较短,保存的信息有限,每个浏览器保存的大小和信息量不一样的。

配置

javax.servlet.ServletConfig

javax.servlet.FilterConfig(since Servlet 2.3 )

输入输出

javax.servlet.ServletInputStream

javax.servlet.ServletOutputStream

对于应用程序而言,servlet是web服务器的一部分,而web服务器是基于socket的,所以servlet和web服务器是类似的,也是二进制的输入输出,编码问题要考虑到是字符流,不是字节流。

异常

javax.servlet.ServletException

Servlet异常有两种,servletException,IOException.

事件(since Servlet 2.3 )

生命周期类型

javax.servlet.ServletContextEvent

javax.servlet.http.HttpSessionEvent

java.servlet.ServletRequestEvent

在servlet里面,所有的事件类都会实现EventListener这个接口,这个接口只是一个标记性接口,在java.util包里面,里面是空的,没有任何方法。

属性上下文类型

javax.servlet.ServletContextAttributeEvent

javax.servlet.http.HttpSessionBindingEvent

javax.servlet.ServletRequestAttributeEvent

监听器(since Servlet 2.3)

生命周期类型

javax.servlet.ServletContextListener

javax.servlet.http.HttpSessionListener

javax.servlet.http.HttpSessionActivationListener

javax.servlet.ServletRequestListener

属性上下文类型

javax.servlet.ServletContextAttributeListener

javax.servlet.http.HttpSessionAttributeListener

javax.servlet.http.HttpSessionBindingListener

javax.servlet.ServletRequestAttributeListener

组件申明注解

@javax.servlet.annotation.WebServlet

@javax.servlet.annotation.WebFilter

@javax.servlet.annotation.WebListener

@javax.servlet.annotation.ServletSecurity,不用太关心,实际中会用很多其他的方式来代替他,其他的方式会比servlet更灵活一些。

@javax.servlet.annotation.HttpMethodConstraint

@javax.servlet.annotation.HttpConstraint

SpringBoot是通过main方法来启动的,有个annotation web的applicationContext来进行初始化的,以前是有个启动类,这个类会创建新的上下文,springMVC 的启动是通过dispatcherServlet来构建的,而SpringBoot是把dispatcherServlet作为一个组件(@bean)来初始化了,就不会出现脱钩的情况。

假如代码是在第三方包里的,实现servlet时,它是2.4版本的,无法用注解(3.0)实现,就要用 new ServletRegistrationBean().addURLMappings(“/aaa/aaa”)这种方式来实现。

配置申明

@javax.servlet.annotation.WebInitParam

上下文,servlet 3.1另外一个最大的亮点就是异步上下文

javax.servlet.AsyncContext

事件

javax.servlet.AsyncEvent

监听器

javax.servlet.AsyncListener

Servlet 组件注册

javax.servlet.ServletContext#addServlet()

javax.servlet.ServletRegistration

Filter 组件注册

javax.servlet.ServletContext#addFilter()

javax.servlet.FilterRegistration

监听器注册

javax.servlet.ServletContext#addListener()

javax.servlet.AsyncListener

自动装配

初始器

javax.servlet.ServletContainerInitializer

类型过滤

@javax.servlet.annotation.HandlesTypes

Servlet 生命周期

初始化

当容器启动或者第一次执行时,Servlet#init(ServletConfig)方法被执行,初始化当前Servlet 。

处理请求

当HTTP 请求到达容器时,Servlet#service(ServletRequest,ServletResponse) 方法被执行,来处理请求。

销毁

当容器关闭时,容器将会调用Servlet#destroy 方法被执行,销毁当前Servlet。

Filter 生命周期

初始化

当容器启动时,Filter#init(FilterConfig)方法被执行,初始化当前Filter。

处理请求

当HTTP 请求到达容器时,Filter#doFilter(ServletRequest,ServletResponse,FilterChain) 方法被执行,来拦截请求,在Servlet#service(ServletRequest,ServletResponse) 方法调用前执行。

销毁

当容器关闭时,容器将会调用Filter#destroy 方法被执行,销毁当前Filter。

Servlet在SpringBoot中的使用

Servlet 组件扫描

注解方式注册

Servlet,Filter,监听器

Spring Boot API方式注册:1.实现一个接口;2.打上一个标记@。。。。

@org.springframework.boot.web.servlet.ServletComponentScan,指定包路径扫描

String[] value() default {}

String[] basePackages() default {}

指定类扫描

Class<?>[] basePackageClasses() default {}

Servlet 组件

扩展 javax.servlet.Servlet

javax.servlet.http.HttpServlet

org.springframework.web.servlet.FrameworkServlet

标记 @javax.servlet.annotation.WebServlet

Filter 组件

实现 javax.servlet.Filter

org.springframework.web.filter.OncePerRequestFilter

标记 @javax.servlet.annotation.WebFilter

监听器组件

实现Listener接口

javax.servlet.ServletContextListener

javax.servlet.http.HttpSessionListener

javax.servlet.http.HttpSessionActivationListener

javax.servlet.ServletRequestListener

javax.servlet.ServletContextAttributeListener

javax.servlet.http.HttpSessionAttributeListener

javax.servlet.http.HttpSessionBindingListener

javax.servlet.ServletRequestAttributeListener

标记 @javax.servlet.annotation.WebListener

前面的都是依赖于servlet组件,现在才是依赖于springboot自己的组件

Servlet 组件

扩展 javax.servlet.Servlet

javax.servlet.http.HttpServlet

org.springframework.web.servlet.FrameworkServlet

组装 Servlet

Spring Boot 1.4.0 开始支持

org.springframework.boot.web.servlet.ServletRegistrationBean

Spring Boot 1.4.0 之前

org.springframework.boot.context.embedded.ServletRegistrationBean

暴露 Spring Bean

@Bean

Filter 组件

实现 javax.servlet.Filter

org.springframework.web.filter.OncePerRequestFilter

组装 Filter

Spring Boot 1.4.0 开始

org.springframework.boot.web.servlet.FilterRegistrationBean

Spring Boot 1.4.0 之前

org.springframework.boot.context.embedded.FilterRegistrationBean

暴露 Spring Bean

@Bean

监听器组件

实现 Listener

组装 Listener

Spring Boot 1.4.0 开始

org.springframework.boot.web.servlet.ServletListenerRegistrationBean

Spring Boot 1.4.0 之前

org.springframework.boot.context.embedded.ServletListenerRegistrationBean

激活

激活 传统Servlet Web部署

Spring Boot 1.4.0 开始

org.springframework.boot.web.support.SpringBootServletInitializer

组装 org.springframework.boot.builder.SpringApplicationBuilder

配置JSP视图

org.springframework.boot.autoconfigure.web.WebMvcProperties

spring.mvc.view.prefix

spring.mvc.view.suffix

Tomcat 8 性能比6,7都要高一点,所以嵌入式容器性能要稍微高一点,SpringBoot性能大概比spring高1.1倍左右(阿里做压测时的结论)

从SpringBoot1.4开始就没有log4j1了,就只有log4j2,logback了,不建议升级到1.5版本,可以升级到2.0版本。

SpringMVC的上下文是通过dispatcherServlet去构建的,SpringBoot是把dispatcherServlet作为一个组件进行初始化了,打上了@Bean的标记。

前后端分离项目,如果页面变化比较少,用模板引擎会更好。

写代码的时候注意对重载方法的思考,增加灵活性,减少代码的漏洞。

默认的SpringBoot对JSP是不支持的,必须激活传统的Web Servlet部署。因为unertow这种非servlet容器是不支持jsp的,所以jsp在SpringBoot上是受限制的,SpringBoot更希望你用相应的模板引擎,而不是jsp。

Web-inf目录在java里面是读不到的。

War包是maven的标准方式。

SpringBoot版本 Spring版本

1.5 4.3

SpringBoot 1.3-1.5坑很多,建议直接升级到2.0,。1.5版本很多东西删掉了,1.4开始就没有log4j-1了,只有log4j-2,logback了。VelocityEngineFactory这个接口在Spring中已经被移除了,Boot 1.5也被移除了。不建议升级到1.5版本。

一般做微服务的时候,依赖和jar包就不能太多,Boot是用自动装配的方式做的,需要关注的东西较多,维护起来的话比以前更麻烦,必须要搜好多的代码,要对spring有很多了解,对底层的原理,机制要很熟悉,大项目的组件没必要用Boot。

前后端分离,做的比较纯的就不需要模板引擎了,只需要json,xml就可以了,用ajax请求。模板引擎的好处是,如果用json或js这种方式的话,数据更新必然会很小,如果数据更新很多,就会在不同的地方增加很多代码,可读性差,不好维护,有个模板直接引入就会方便很多。看页面交互的情况。


上一篇:SpringWebMVC



版权声明:本文为lx_Frolf原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。