转载

Spring Boot-嵌入式Servlet容器&三大组件

Spring Boot-嵌入式Servlet容器&三大组件

这篇博客,只是简述如何去使用, 不会有太深的分析 , 我觉得一个东西要先会用再去学习底层原理,会更加的顺畅一点。

配置

Spring Boot默认是使用 Tomcat 作为嵌入式的Servlet容器;

1.如何定制和修改Servlet容器的相关配置?

1)修改propertis/yml配置文件:

  • 示例
server.port=8080
server.tomcat.uri-encoding=UTF-8
...
...
复制代码

2)代码实现方式

package com.carson.springboot.config;

import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MyServerConfig {

    // 配置servlet容器
    @Bean
    public ConfigurableServletWebServerFactory configurableServletWebServerFactory(){
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        factory.setPort(8080);
        return factory;
    }

}

复制代码

2. 注册 Servlet,Filter,Listener 三大组件

  • Servlet 代码示例:

创建一个类 MyServlet 继承 HttpServlet

package com.carson.springboot.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class MyServlet extends HttpServlet {

    // 处理get请求

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
	
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.getWriter().write("Hello MyServlet");
    }
}

复制代码
  • 再从刚才的 MyServerConfig 类 添加一个方法
// 注册三大组建的 Servlet
    @Bean 
    public ServletRegistrationBean myServlet(){
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
        // MyServlet 就是刚才写的类
        return registrationBean;
    }
复制代码

参数说明: new ServletRegistrationBean(传入哪一个Servlet,拦截哪个路径)

校验是否生效: 访问 /myServlet 查看效果

Spring Boot-嵌入式Servlet容器&三大组件

可以看到输出的 字符串内容,说明生效了

  • Filter 代码示例

package com.carson.springboot.filter;

import javax.servlet.*;
import java.io.IOException;

public class MyFilter implements Filter {

    @Override //初始化
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override // 过滤
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        System.out.println("MyFilter RUN!!!!");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override // 销毁
    public void destroy() {

    }
}

复制代码

也是创建一个自己的filter类,实现Filter接口,注意是 import javax.servlet.*; 包下的Filter

初始化和销毁就先不写了,只写运行中时候

  • 再次来到刚才的 MyServerConfig 类

加上以下代码

// 2.注册 Filter
    @Bean
    public FilterRegistrationBean myFilter(){
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean();
        // 设置一个 Filter 也就是我刚才自定义的 类
        filterRegistrationBean.setFilter(new MyFilter());
        // 设置 拦截路径(可多个)
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
        return filterRegistrationBean;
    }
复制代码

setUrlPatterns默认需要传入一个集合,我转成了数组

Spring Boot-嵌入式Servlet容器&三大组件

试验一下:

访问 http://localhost:8080/hello 或者 http://localhost:8080/myServlet :

查看idea控制台:point_down:

Spring Boot-嵌入式Servlet容器&三大组件

打印出了 MyFilter RUN!!!! 说明刚才的 doFilter 执行了!

Spring Boot-嵌入式Servlet容器&三大组件
  • Listener

编写一个MyListener类:

package com.carson.springboot.listener;

import javax.servlet.Servlet;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class MyListener implements ServletContextListener{

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("contextInitialized..web应用启动");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("contextDestroyed..当前web项目销毁");
    }
}

复制代码

注册一下(这里依然是刚才的 MyServerConfig 类):

// 3.注册 listener
    @Bean
    public ServletListenerRegistrationBean servletListenerRegistrationBean(){
        ServletListenerRegistrationBean mylistener = new ServletListenerRegistrationBean(new MyListener());
        return mylistener;
    }
复制代码

试验:

  1. 启动 项目
Spring Boot-嵌入式Servlet容器&三大组件

我们看到了 启动

我们再试一下销毁

注意!!! : 这里的销毁 不可以 直接按:

Spring Boot-嵌入式Servlet容器&三大组件

按这个里就看不到销毁字符串了

应该按 这里:

Spring Boot-嵌入式Servlet容器&三大组件
Spring Boot-嵌入式Servlet容器&三大组件

看到销毁表示我的 listener 正常执行了

Spring Boot 底层帮我们自动配置SpringMVC的时候,也帮我们配置了 前端控制器 DispatcherServlet

基本的配置原理也和三大组件差不太多,这里就不多赘述了

如何使用其他Servlet容器?

Spring Boot 除了 Tomcat(默认的) 以外 还支持:

  • Jetty (适合长时间连接)
  • Undertow (不支持JSP)

这两个容器

要想使用 其他的容器,就需要先把 tomcat 给除掉!

pom.xml 文件下 ctrl+alt+shift+u 打开依赖网

或者鼠标右键 :point_down:

Spring Boot-嵌入式Servlet容器&三大组件
Spring Boot-嵌入式Servlet容器&三大组件

排除方法

Spring Boot-嵌入式Servlet容器&三大组件
Spring Boot-嵌入式Servlet容器&三大组件

然后添加 jetty的依赖:

<!-- 引入其他的servlet容器-->
        <dependency>
            <artifactId>spring-boot-starter-jetty</artifactId>
            <groupId>org.springframework.boot</groupId>
        </dependency>
复制代码

修改刚才的 MyServerConfig 类中的代码:

// 配置servlet容器
    @Bean
    public ConfigurableServletWebServerFactory configurableServletWebServerFactory(){
        //TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();
        JettyServletWebServerFactory jettyServletWebServerFactory = new JettyServletWebServerFactory();
        jettyServletWebServerFactory.setPort(9192);
       // factory.setPort(8080);
        return jettyServletWebServerFactory;
    }
复制代码

从名称上可以看出来 一个是 tomcat 一个是 jetty

运行程序:

Spring Boot-嵌入式Servlet容器&amp;三大组件

我发现 端口号是我刚才设置的端口,并且 三大组件 还在生效

就算是切换Undertow 也是一样的流程,这里我就写一下代码看一下,就不再来一遍了:

UndertowServletWebServerFactory undertowServletWebServerFactory = new UndertowServletWebServerFactory();
        undertowServletWebServerFactory.setPort(8080);
复制代码

切换其他容器就写完了,我这边要再换回 tomcat 以防止出什么问题,毕竟我一开始就是以Tomcat为基础写的程序

原文  https://juejin.im/post/5d26e6846fb9a07eb74b675b
正文到此结束
Loading...