Web 的原生组件:指的就是 servlet 开发里边的 Servlet、Filter、Listener 。

官方文档位置:https://docs.spring.io/spring-boot/docs/current/reference/html/spring-boot-features.html#boot-features-embedded-container

以前要注入这三大组件,是要把三大组件写好之后,配在 xml 中。

现在使用 Spring Boot 开发,我们就来看第一种方式:使用 Servlet API 的方式。根据官方文档的说明,使用 @WebServlet 、@WebFilter 、@WebListener ,再使用 @ServletComponentScan 注解启用它们即可。
image.png

@ServletComponentScan

在主程序中使用该注解声明 servlet 的包扫描路径,如果 servlet 类放在主程序所在的包下,basePackages 参数可以不填写,Spring Boot 会自动扫描。

  1. @ServletComponentScan(basePackages = "com.example.admin")
  2. @SpringBootApplication
  3. public class SpringbootAdminApplication {
  4. public static void main(String[] args) {
  5. SpringApplication.run(SpringbootAdminApplication.class, args);
  6. }
  7. }

@WebServlet

编写 servlet ,并使用该注解标注处理路径。

  1. @WebServlet(urlPatterns = "/my")
  2. public class MyServlet extends HttpServlet {
  3. @Override
  4. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
  5. resp.getWriter().write("6666");
  6. }
  7. }

访问:
http://127.0.0.1/my
image.png

扩展

DispatchServlet 如何注册进来?

为什么 servlet 直接响应,没有经过 Spring Boot 的拦截器?

在使用 Tomcat-Servlet 开发时,如果多个 Servlet 都能处理到同一层路径,那应该是精确匹配原则。

例如:
A Servlet 能处理的路径是 /my
B Servlet 能处理的路径是 /my/1

此时,如果请求是 /my/1 ,我们会优先来到 B 处理,如果是 /my/2 ,则来到 A 处理。

现在整个系统里有两个 Servlet:
1)DispatchServlet ,它处理的路径是 /
2)MyServlet ,它处理的路径是 /my

所以当我们访问 /my 路径时,按照精确优先原则,它会先来到 MyServlet 处理。而如果我们没有 MyServlet ,我们访问 /my 路径时,那它就会来到 DispatchServlet 。

所以一旦来到 DispatchServlet ,那整个执行的就是 Spring 的那堆流程,拦截器的流程才会被触发。
而我们这个 MyServlet ,是直接交由 Tomcat 处理的,由 Tomcat 拿到内容,直接响应出去。

@WebFilter

servlet 是单星号路径匹配, Spring Boot 是双星号。所以此处写单星号。

  1. @WebFilter(urlPatterns = {
  2. "/css/*",
  3. "/images/*"
  4. })
  5. @Slf4j
  6. public class MyFilter implements Filter {
  7. @Override
  8. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  9. log.info("MyFilter工作");
  10. chain.doFilter(request, response);
  11. }
  12. @Override
  13. public void init(FilterConfig filterConfig) throws ServletException {
  14. log.info("MyFilter初始化完成");
  15. }
  16. @Override
  17. public void destroy() {
  18. log.info("MyFilter销毁");
  19. }
  20. }

访问:
http://127.0.0.1/css/bootstrap.min.css
image.png
image.png
可以看到控制台也输出了相应的内容。