SpringBoot原生组件注入实现两种方式介绍
原生组件注入SpringBoot,即注册 Servlet 、Filter、Listener 进入 SpringBoot
一、使用 Servlet API
使用 Servlet API 可以实现原生组件注入,通过在自定义 Servlet 前加入 @WebServlet
注释,并且在 SpringBoot 启动类前加入 @ServletComponentScan
注释,可实现注册 Servlet
代码示例:
1、实现自定义 MyServlet
自定义 Servlet 类:
@WebServlet(urlPatterns = "/my") // 加入 @WebServlet 注释 public class MyServlet extends HttpServlet { // 注意要继承 HttpServlet 类 @Override // 重写 DoGet 方法 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.getWriter().println("haha"); } }
项目启动类:
@ServletComponentScan(basePackages = "com.wanqing.admin") //扫描那个包中有servlet @SpringBootApplication public class DemoAdminApplication { public static void main(String[] args) { SpringApplication.run(DemoAdminApplication.class, args); } }
2、实现自定义 MyFilter
@Slf4j @WebFilter(urlPatterns = {"/css/*", "/images/*"}) // 拦截静态资源 public class MyFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); 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() { Filter.super.destroy(); log.info("MyFilter销毁"); } }
3、实现自定义 MyServletContextListener
@WebListener @Slf4j public class MyServletContextListener implements ServletContextListener { @Override public void contextInitialized(ServletContextEvent sce) { log.info("MyServletContextListener 监听到项目初始化完成"); } @Override public void contextDestroyed(ServletContextEvent sce) { log.info("MyServletContextListener 监听到项目销毁"); } }
二、使用 RegistrationBean 的方式注入原生组件
通过编写 MyRegistConfig 配置类,返回 RegistrationBean 的方式实现组件的注入,与上一种方式的区别在于,这种方式不需要给 自定义 Servlet 类写 @WebServlet 注释。
注意点:要记得使用 @Bean 注释将 ServletRegistrationBean 注册到容器中。
代码示例:
自定义 MyRegistConfig 配置类,注册 myServlet 组件,返回 ServletRegistrationBean 对象 (对象参数为自定义的 myServlet 对象实例)
myFilter 及myListener 的实现方式同理
@Configuration public class MyRegistConfig { @Bean public ServletRegistrationBean myServlet(){ MyServlet myServlet = new MyServlet(); return new ServletRegistrationBean(myServlet, "/my","/my02"); } @Bean public FilterRegistrationBean myFilter(){ MyFilter filter = new MyFilter(); //return new FilterRegistrationBean(filter, myServlet()); // 拦截myServlet()的路径 FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(filter); filterRegistrationBean.addUrlPatterns("/my","/css/*"); return filterRegistrationBean; } @Bean public ServletListenerRegistrationBean myListener(){ MyServletContextListener myServletContextListener = new MyServletContextListener(); return new ServletListenerRegistrationBean(myServletContextListener); } }
拓展:为什么拦截器不拦截 我们自定义的 MyServlet 请求?
分析 DispatcherServlet 如何注册进入容器中,从 DispatcherServletAutoConfiguration 类开始
容器中自动配置了 DispatcherServlet 组件,其属性绑定到 WebMvcProperties 中,对应的配置文件是 spring.mvc
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) // 注册 DispatcherServlet 组件 public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest()); dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound()); dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents()); dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails()); return dispatcherServlet; }
通过 ServletRegistrationBean < DispatcherServlet > 机制(DispatcherServletRegistrationBean.class)将 DispatcherServlet 原生的 Servlet 组件配置进来
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet, WebMvcProperties webMvcProperties, ObjectProvider<MultipartConfigElement> multipartConfig) { DispatcherServletRegistrationBean registration = new DispatcherServletRegistrationBean(dispatcherServlet, webMvcProperties.getServlet().getPath()); // 拿到默认映射路径为 / 路径 registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); registration.setLoadOnStartup(webMvcProperties.getServlet().getLoadOnStartup()); multipartConfig.ifAvailable(registration::setMultipartConfig); return registration; }
拿到默认映射路径 /
WebMvcProperties.class 中配置
使用 Tomcat 做原生 Servlet 开发,如果多个 Servlet 都能处理到同一层路径,是精确优先原则,例如:
A:/my/
B: /my/1
发送 /my/1 请求 B处理,而发送 /my/2 请求 A 处理
结论 : 来到 /my 不经过 / —— 精确匹配 /my 直接经 Tomcat 写出响应,不经过 SpringMVC 的一系列流程,因此不被拦截器拦截,如下图所示:
到此这篇关于SpringBoot原生组件注入实现两种方式介绍的文章就介绍到这了,更多相关SpringBoot原生组件注入内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://blog.csdn.net/liuwanqing233333/article/details/12739
相关文章
解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题
这篇文章主要介绍了解决springboot使用logback日志出现LOG_PATH_IS_UNDEFINED文件夹的问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-28- 这篇文章主要为大家详细介绍了SpringBoot实现excel文件生成和下载,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-02-09
- 这篇文章主要介绍了详解springBoot启动时找不到或无法加载主类解决办法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
- 这篇文章主要介绍了SpringBoot集成Redis实现消息队列的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-02-10
- 这篇文章主要介绍了解决Springboot get请求是参数过长的情况,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-17
Spring Boot项目@RestController使用重定向redirect方式
这篇文章主要介绍了Spring Boot项目@RestController使用重定向redirect方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-02- 这篇文章主要介绍了Springboot+TCP监听服务器搭建过程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-10-28
- 这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
springboot中使用@Transactional注解事物不生效的坑
这篇文章主要介绍了springboot中使用@Transactional注解事物不生效的原因,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-01-26- 这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
详解SpringBoot之访问静态资源(webapp...)
这篇文章主要介绍了详解SpringBoot之访问静态资源(webapp...),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-14- 这篇文章主要介绍了springboot多模块包扫描问题的解决方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-09-16
Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用详解
这篇文章主要介绍了Springboot mybatis plus druid多数据源解决方案 dynamic-datasource的使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-11-18- 这篇文章主要介绍了Springboot实现多线程注入bean的工具类操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-27
Springboot+MDC+traceId日志中打印唯一traceId
本文主要介绍了Springboot+MDC+traceId日志中打印唯一traceId,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-17SpringBoot部署到Linux读取resources下的文件及遇到的坑
本文主要给大家介绍SpringBoot部署到Linux读取resources下的文件,在平时业务开发过程中,很多朋友在获取到文件内容乱码或者文件读取不到的问题,今天给大家分享小编遇到的坑及处理方案,感兴趣的朋友跟随小编一起看看吧...2021-06-21- 这篇文章主要介绍了springboot中nacos动态路由的配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-11
SpringBoot高版本修改为低版本时测试类报错的解决方案
这篇文章主要介绍了SpringBoot高版本修改为低版本时测试类报错的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-18解决Springboot整合shiro时静态资源被拦截的问题
这篇文章主要介绍了解决Springboot整合shiro时静态资源被拦截的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-26springboot配置多数据源后mybatis拦截器失效的解决
这篇文章主要介绍了springboot配置多数据源后mybatis拦截器失效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-23