SpringBoot原生组件注入实现的方式有哪些

这篇文章主要介绍了SpringBoot原生组件注入实现的方式有哪些的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇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 不经过 / &mdash;&mdash; 精确匹配 /my 直接经 Tomcat 写出响应,不经过 SpringMVC 的一系列流程,因此不被拦截器拦截,如下图所示:

    关于“SpringBoot原生组件注入实现的方式有哪些”这篇文章的内容就介绍到这里,感谢各位的阅读!相信大家对“SpringBoot原生组件注入实现的方式有哪些”知识都有一定的了解,大家如果还想学习更多知识,欢迎关注本站行业资讯频道。

    相关推荐:

    Springboot如何查询MySQL DATE字段?

    springboot日期查询mysql date字段时的问题 在使用springboot查询mysql date字段时,可能会遇到日期类型不匹配的问题。这是因为springboot接收时间时默认为timestamp类型,而mysql date字段是日期类型。 解决方案 解决方法是将前端传来的日期字符串直接转换成date类型,然后使用mybatis-plus进行查询。代码示例如下:// 后端参数接收...

    springboot怎么集成shiro框架

    要在Spring Boot项目中集成Apache Shiro框架,可以按照以下步骤进行操作: 添加依赖:在pom.xml文件中添加Shiro和Spring Boot Shiro相关的依赖。例如: <dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot...

    SpringBoot CommandLine如何配置

    SpringBoot CommandLine是一个用于构建命令行应用的工具。要配置SpringBoot CommandLine,可以按照以下步骤进行操作: 添加依赖:在项目的pom.xml文件中添加SpringBoot CommandLine的依赖。 <dependency> <groupId>org.springframework.boot</groupId>...

    SpringBoot CommandLine的优势何在

    Spring Boot CommandLine 的优势主要有以下几点: 简化开发流程:Spring Boot CommandLine 可以帮助开发者快速构建命令行应用程序,简化了配置和开发流程。开发者只需要关注业务逻辑的实现,而不需要花费大量的时间去配置项目。 集成了常用功能:Spring Boot CommandLine 提供了许多常用的功能和组件,例如参数解析、命令行选项、日志记录等,开发者可...

    使用SpringBoot CommandLine需要注意什么

    在使用Spring Boot CommandLine时,需要注意以下几点: 引入必要的依赖:在pom.xml文件中添加Spring Boot CommandLine的依赖,如spring-boot-starter,spring-boot-starter-web等。 创建主应用程序类:创建一个包含main方法的主应用程序类,并使用@SpringBootApplication注解标记它。 实现命令行应...

    SpringBoot CommandLine可以做哪些事情

    Spring Boot CommandLine 可以用于以下几个方面: 运行Spring Boot应用程序:使用CommandLine可以直接在命令行中启动Spring Boot应用程序,而不需要使用IDE或者构建工具。 执行自定义命令:通过CommandLine可以执行自定义命令,例如初始化数据库、调用外部API、生成报告等。 与操作系统交互:可以通过CommandLine与操作系统交互,执行系...

    SpringBoot CommandLine怎样解析参数

    SpringBoot应用程序可以通过CommandLineRunner接口来解析命令行参数。以下是一个简单的示例: 首先,创建一个CommandLineRunner接口的实现类,并实现run方法: import org.springframework.boot.CommandLineRunner; import org.springframework.stereotype.Component; @...

    SpringBoot CommandLine与Shell脚本如何交互

    要在SpringBoot应用中与Shell脚本交互,可以使用Java中的ProcessBuilder类来执行Shell命令,并通过标准输入输出流来与Shell脚本交互。 以下是一个简单的示例代码,演示了如何在SpringBoot应用中执行Shell脚本并与其交互: import java.io.BufferedReader; import java.io.IOException; import j...