乐趣区

关于java:6SpringBoot之Web原生组件注入ServletFilterListener

1、应用 Servlet API

  • 注入 Servlet:

@ServletComponentScan(basePackages = “com.atguigu.admin”):指定原生 Servlet 组件都放在那里
@WebServlet(urlPatterns = “/my”):成果:间接响应, 没有通过 Spring 的拦截器?

/*
步骤:应用 @WebServlet 注解并设置匹配的门路 + @ServletComponentScan 扫描 Servlet 组件
    继承 HttpServlet 类并重写办法
*/
@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {resp.getWriter().write("666");
    }
}
@ServletComponentScan(basePackages = "com.atguigu.admin")// 扫描 Servlet 组件
@SpringBootApplication
public class Boot05WebAdminApplication {public static void main(String[] args) {SpringApplication.run(Boot05WebAdminApplication.class, args);
    }

}
  • 注入 Filter:@WebFilter(urlPatterns={“/css/*”,“/images/*”})
/*
步骤:应用 @WebFilter 注解并设置拦挡门路
    实现 Filter 接口并重写办法
*/
@Slf4j
@WebFilter(urlPatterns = {"/css/*","/images/*"})
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {log.info("MyFilter 初始化实现。。。。。。。。。");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {log.info("MyFilter 执行过滤。。。。。。。。。");
        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {log.info("MyFilter 销毁。。。。。。。。。");
    }
}
  • 注入 Listener:@WebListener
/*
步骤:应用 @WebListener 注解
    实现 ServletContextListener 接口并实现办法
*/
@Slf4j
@WebListener
public class MyListener implements ServletContextListener {
    // 我的项目 一运行就执行这个办法
    @Override
    public void contextInitialized(ServletContextEvent sce) {log.info("MyListener 监听到我的项目初始化实现");
    }

    // 我的项目真正被停掉后才执行办法(点 idea 里的红色小正方形按钮没无效)
    @Override
    public void contextDestroyed(ServletContextEvent sce) {log.info("MyListener 监听到我的项目被终止了");
    }
}

举荐能够这种形式:

2、应用 RegistrationBean

ServletRegistrationBean, FilterRegistrationBean, ServletListenerRegistrationBean
先把 @WebServlet,@WebFilter,@WebListener 这三个注解正文掉

@Slf4j
//@WebServlet(urlPatterns = "/my")
public class MyServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {log.info("servlet 执行");
        resp.getWriter().write("666");
    }
}
@Slf4j
//@WebFilter(urlPatterns = {"/css/*","/images/*"})
public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {log.info("MyFilter 初始化实现。。。。。。。。。");
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {log.info("MyFilter 执行过滤。。。。。。。。。");
        filterChain.doFilter(servletRequest,servletResponse);

    }

    @Override
    public void destroy() {log.info("MyFilter 销毁。。。。。。。。。");
    }
}
@Slf4j
//@WebListener
public class MyListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent sce) {log.info("MyListener 监听到我的项目初始化实现");
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {log.info("MyListener 监听到我的项目被终止了");
    }
}
// 将这个类标注为配置类,并保障每个 @Bean 办法被调用多少次返回的组件都是单实例的
@Configuration(proxyBeanMethods = true)
public class MyRegistConfig {
    @Bean
    public ServletRegistrationBean myservlet(){MyServlet myServlet = new MyServlet();
        return new ServletRegistrationBean(myServlet,"/my","/my2");
    }

    @Bean
    public FilterRegistrationBean myFilter(){MyFilter myFilter = new MyFilter();
        // 第一种写法
        //Servlet 拦挡的是什么门路,我 Filter 就拦挡什么门路
//        return new FilterRegistrationBean(myFilter,myservlet());
        /*
        * 第二种写法
        * 能够本人设置拦挡什么门路
        * */
        FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(myFilter);
        filterRegistrationBean.setUrlPatterns(Arrays.asList("/my","/css/*"));
        return filterRegistrationBean;
    }

    @Bean
    public ServletListenerRegistrationBean myListener(){MyListener myListener = new MyListener();
        return new ServletListenerRegistrationBean(myListener);
    }
执行程序:执行 Listener 的 contextInitialized 容器初始化办法 -> 执行 Filter 的 init 初始化办法
-> 执行 Filter 的 doFilter 办法 -> 执行 Servlet 的 doGet 或 doPost 办法
-> 执行 Filter 的 destroy 办法 -> 执行 Listener 的 contextDestroyed 销毁办法

扩大:DispatchServlet 如何注册进来

  • 容器中主动配置了 DispatcherServlet,属性绑定到 WebMvcProperties 类;对应的配置文件配置项(prefix 前缀)是 spring.mvc。
  • 通过 ServletRegistrationBean<DispatcherServlet> 把 DispatcherServlet 配置进来。
  • 默认映射的是 / 门路。所以我的项目下的所有申请都来到 DispatchServlet 解决

以前应用 Tomcat 做原生的 Servlet 开发的时候:

多个 Servlet 都能解决到同一层门路时,应用 准确优选准则

A:/my/   如果发的是 /my/ 申请,他会先来到 A 解决
B:/my/1  如果发的是 /my/ 1 申请,他会先来到 b 解决
总结:DispatchServlet 如何注册进来?应用 RegistrationBean 把 DispatchServlet 它映射 / 门路注册进来的。
退出移动版