Spring Boot 2.x实战48 - Spring Web MVC 20 - Servlet容器(如何注册Servlet、Filter和listener)

4. Servlet容器

Spring Boot使用的是内嵌式的Servlet容器,支持tomcat、jetty和undertow。

4.1 注册Servlet、Filter和listener

Spring Boot下我们可以用多种形式注册Servlet、Filter和Listener,我们先定义三个简单的示例:

Servlet:

@Slf4j
@Getter
@Setter
public class CustomServlet extends HttpServlet {
    private String msg;

    public CustomServlet(String msg) {
        this.msg = msg;
    }


    @Override
    public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
        PrintWriter writer = res.getWriter();
        writer.println("Welcome " + msg);
        writer.close();
        log.info("--CustomServlet/service---");
    }

}

Filter:

@Slf4j
public class CustomFilter extends HttpFilter {
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        log.info("--CustomFilter/doFilter---");
        chain.doFilter(request, response);
    }
}

Listener:

@Slf4j
public class CustomListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("--CustomListener/contextInitialized---");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("--CustomListener/contextDestroyed---");
    }
}
4.1.1 以Bean形式注册

在Spring Boot下我们可以直接注册Servlet、Filter、Listener的Bean。Spring Boot给我们以下的默认:

  • Servlet:多个Servlet Bean映射的路径为Bean的名称
  • Filter:默认映射到/*
@Bean
public CustomServlet customServlet(){
    return new CustomServlet("Custom Servlet");
}

@Bean
public CustomServlet customServlet2(){
    return new CustomServlet("Custom Servlet2");
}

@Bean
public CustomFilter customFilter(){
    return new CustomFilter();
}

@Bean
public CustomListener customListener(){
    return new CustomListener();
}

在这里插入图片描述
如果默认Bean配置不能满足要求,我们需要使用*RegistrationBean来注册。

4.1.2 以*RegistrationBean注册

我们可以通过定义*RegistrationBean的Bean来注册Servlet、Filter、Listener,通过ServletRegistrationBeanFilterRegistrationBeanServletListenerRegistrationBean的方法来对Servlet、Filter、Listener进行完全的控制。

@Bean
public ServletRegistrationBean servletRegistrationBean(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean();
    registrationBean.setServlet(new CustomServlet("Custom Servlet by ServletRegistrationBean"));
    registrationBean.setUrlMappings(Arrays.asList("/custom-servlet"));
    return registrationBean;
}

@Bean
public FilterRegistrationBean filterRegistrationBean(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new CustomFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/*"));
    return registrationBean;
}

@Bean
public ServletListenerRegistrationBean servletListenerRegistrationBean(){
    ServletListenerRegistrationBean registrationBean = new ServletListenerRegistrationBean();
    registrationBean.setListener(new CustomListener());
    return registrationBean;
}

在这里插入图片描述

4.1.3 使用Servlet注解注册

我们可以使用Servlet的注解@WebServlet@WebFilter@WebListener来注解Servlet、Filter和Listener,需通过@ServletComponentScan将它们注册成Bean。

Servlet:

@WebServlet({"/web-servlet"})
public class CustomServlet extends HttpServlet {
  //...
}

Filter:

@WebFilter({"/*"})
public class CustomFilter extends HttpFilter {
  //...
}

Listener:

@WebListener
public class CustomListener implements ServletContextListener {
  //...
}

通过@ServletComponentScan注解扫描注册:

@Configuration
@ServletComponentScan({"top.wisely.learningspringmvc.servlet"})
public class WebConfiguration implements WebMvcConfigurer {
    @Bean
    String msg(){
        return "Custom Servlet by Sevlet annotation";
    }
}

在这里插入图片描述

4.1.4 ServletContextInitializer

在Servlet 3.0之前,Servlet容器初始化通过的是web.xml;Servlet 3.0时javax.servlet.ServletContainerInitializer接口的实现类来初始化Servlet容器;在Spring MVC 下是org.springframework.web.WebApplicationInitializer接口的实现;在Spring Boot的内嵌式Servlet容器下,我们通过定义org.springframework.boot.web.servlet.ServletContextInitializer接口的实现的Bean来初始化Servlet容器。

我们可以通过重载ServletContextInitializer的方法onStart即可定制初始化Servlet容器,而ServletContextInitializer是一个函数接口,所以定义ServletContextInitializer是简单而简介的。

@Bean
ServletContextInitializer servletContextInitializer(){
  return servletContext -> {
     servletContext.addServlet("new servlet", new CustomServlet("Custom Servlet by ServletContextInitializer"))
             .addMapping("/new-servlet"); 
     servletContext.addFilter("new filter", new CustomFilter())
             .addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*");
     servletContext.addListener(new CustomListener());

  };
}

在这里插入图片描述

新书推荐:

我的新书《从企业级开发到云原生微服务:Spring Boot 实战》已出版,内容涵盖了丰富Spring Boot开发的相关知识
购买地址:https://item.jd.com/12760084.html

在这里插入图片描述
主要包含目录有:

第一章 初识Spring Boot(快速领略Spring Boot的美丽)
第二章 开发必备工具(对常用开发工具进行介绍:包含IntelliJ IDEA、Gradle、Lombok、Docker等)
第三章 函数式编程
第四章 Spring 5.x基础(以Spring 5.2.x为基础)
第五章 深入Spring Boot(以Spring Boot 2.2.x为基础)
第六章 Spring Web MVC
第七章 数据访问(包含Spring Data JPA、Spring Data Elasticsearch和数据缓存)
第八章 安全控制(包含Spring Security和OAuth2)
第九章 响应式编程(包含Project Reactor、Spring WebFlux、Reactive NoSQL、R2DBC、Reactive Spring Security)
第十章 事件驱动(包含JMS、RabbitMQ、Kafka、Websocket、RSocket)
第11章 系统集成和屁股里(包含Spring Integration和Spring Batch)
第12章 Spring Cloud与微服务
第13章 Kubernetes与微服务(包含Kubernetes、Helm、Jenkins、Istio)
多谢大家支持。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值