springboot-Servlet Filter Listener的注入

注入JavaWeb的三大组件:Servlet、Filter、Listener

基本介绍

  1. 考虑到实际开发业务非常复杂和兼容,Spring-Boot支持将Servlet、Filter、Listener注入Spring容器,成为Spring bean

  1. 也就是说明Spring-Boot开放了和原生WEB组件(Servlet、Filter、Listener)的兼容

当使用嵌入式容器时,自动注册含有注解@WebServlet,@WebFilter,@WebListener的类,使用注解@ServletComponentScan(是另外注解到Application.class上的)才会注入到spring容器。


方法一:使用注解方式注入

@ServletComponentScan

需要在Application.class添加注解@ServletComponentScan(basePackages = "com.stein.springboot"),并设置扫描包,这样才能将这三大组件添加到ioc容器。

@ServletComponentScan(basePackages = "com.stein.springboot")
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        ConfigurableApplicationContext ioc
                = SpringApplication.run(Application.class, args);
        System.out.println("hello");
        //ioc.close();//销毁context,查看ServletContextListener监听情况
    }
}

@WebServlet

@WebServlet(urlPatterns = {"/servlet01","/servlet02"})
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=utf-8");
        resp.getWriter().write("doGet()被执行");
    }
}

@WebFilter

@Slf4j
@WebFilter(urlPatterns = {"/css/*","/images/*"})
public class MyFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("filter_init");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("doFilter");
        HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
        log.info("过滤器处理的uri={}",httpServletRequest.getRequestURI());
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {
        log.info("filter-destroy");
    }
}

注意:过滤器配置的urlPatterns也会经过Spring-Boot拦截器(根据拦截器的规则)

所以为了看到效果,请在拦截器配置放行/css/**

在servlet匹配全部是/*,在Spring-Boot是/**

@WebListener

监听器有8种,这儿只是选取了较为常用的ServletContextListener来进行演示。Destroy方法需要在Application.class中调用ioc.close( )才能看到。

@Slf4j
@WebListener
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        log.info("ServletContextListener监听到上下文初始化");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        log.info("ServletContextListener监听到上下文销毁");
    }
}

方式二:使用配置类的方式注入

创建一个配置类,使用@Configuration注解,然后新建一个方法使用@Bean注入,返回XXXRegistrationBean类型的方式来注入。

创建配置类

@Configuration
public class MyServletConfig {  }

ServletRegistrationBean,注入Servlet的注册类型

    @Bean
    public ServletRegistrationBean servlet(){
        MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/servlet01","/servlet02");
    }

通过在浏览器输入:localhost:8080/servlet01 或 servlet02 来查看是否正确执行

FilterRegistrationBean,注入Filter的注册类型

    @Bean
    public FilterRegistrationBean filter(){
        MyFilter myFilter = new MyFilter();
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/css/*","/images/*"));
        return filterRegistrationBean;
    }

通过在浏览器输入: localhost:8080/css/t.css或者localhost:8080/images/logo.png来查看是否注入成功

ServletListenerRegistrationBean,注入Listener的注册类型

    @Bean
    public ServletListenerRegistrationBean listener(){
        MyListener myListener = new MyListener();
        return new ServletListenerRegistrationBean(myListener);
    }

通过查看SpringApplication.run(Application.class, args)的运行或者ioc.close()的关闭来查看Context的监听情况。


请求Servlet时,为什么不会到达拦截器

1.请求Servlet时,不会到达DispatherServlet,因此也不会达到拦截器

2.原因分析

  • 注入的Servlet会存在Spring容器中

  • DispatherServlet也存在Spring容器中

springboot-Servlet Filter Listener的注入_第1张图片

3.回忆一下Tomcat在对Servlet url匹配的原则,多个servlet都能处理到同一层路径,精确优先原则/最长前缀匹配原则

4. debug源码

5.在SpringBoot中,去调用@Controller目标方法是按照DispatherServlet分发匹配的机制,请回顾一下我们自己实现SpringMVC的底层机制的程序。

你可能感兴趣的:(SpringBoot,servlet,spring,boot,java)