SpringBoot原生组件注入实现两种方式介绍

目录
  • 一、使用 Servlet API
    • 1、实现自定义 MyServlet
    • 2、实现自定义 MyFilter
    • 3、实现自定义 MyServletContextListener
  • 二、使用 RegistrationBean 的方式注入原生组件

原生组件注入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原生组件注入内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • SpringBoot2零基础到精通之异常处理与web原生组件注入

    目录 1 异常处理 1.1 异常处理之错误页面 1.2 异常处理之精确捕获 1.3 异常处理之自定义异常 1.4 异常处理之框架底层异常 2 web原生组件的注入 2.1 servlet组件 2.2 filter组件 2.3 listener组件 3 web实现定制化总结 1 异常处理   默认情况下,SpringBoot会提供/error处理所有的错误请求并返回相应的信息,对于浏览器客户端来说会返回一个包含时间戳.状态码.错误信息.携带的自定义异常信息.发生错误的路径等信息的错误Whitela

  • SpringBoot原生组件注入实现两种方式介绍

    目录 一.使用 Servlet API 1.实现自定义 MyServlet 2.实现自定义 MyFilter 3.实现自定义 MyServletContextListener 二.使用 RegistrationBean 的方式注入原生组件 原生组件注入SpringBoot,即注册 Servlet .Filter.Listener 进入 SpringBoot 一.使用 Servlet API 使用 Servlet API 可以实现原生组件注入,通过在自定义 Servlet 前加入 @WebServ

  • 利用SpringBoot实现多数据源的两种方式总结

    目录 前言 基于dynamic-datasource实现多数据源 dynamic-datasource介绍 dynamic-datasource的相关约定 引入dynamic-datasource依赖 配置数据源 使用 @DS 切换数据源 基于AOP手动实现多数据源 项目工程结构 项目依赖 配置文件 自定义注解 编写DataSourceConstants 动态数据源名称上下文处理 获取当前动态数据源方法 动态数据源配置 AOP切面 编写TestUser实体 TestUserMapper Test

  • 浅谈Springboot实现拦截器的两种方式

    目录 一.拦截器方式 1.配置HandlerInterceptor 2.注册拦截器 3.使用拦截器的坑 二.过滤器方式 1.实现Filter接口 2.使用过滤器需要注意的 实现过滤请求有两种方式: 一种就是用拦截器,一种就是过滤器 拦截器相对来说比较专业,而过滤器虽然不专业但是也能完成基本的拦截请求要求. 一.拦截器方式 1.配置HandlerInterceptor 下面这个也是我们公司项目拦截器的写法,总体来说感觉还不错,我就记录了下来. 利用了一个静态Pattern变量存储不走拦截器的路径,

  • springboot配置多个数据源两种方式实现

    目录 第一种方式: 方法二 在我们的实际业务中可能会遇到:在一个项目里面读取多个数据库的数据来进行展示,spring对同时配置多个数据源是支持的. 本文中将展示两种方法来实现这个功能. springboot+mybatis 第一种方式: 在配置文件中配置多个数据源,然后通过配置类来获取数据源以及mapper相关的扫描配置 pom.xml <parent> <groupId>org.springframework.boot</groupId> <artifactId

  • Vue引入并使用Element组件库的两种方式小结

    目录 前言 Element-ui(饿了么ui) 安装element-ui 引入element-ui 完整引入element-u 按需引入element-ui 总结 前言 在开发的时候,虽然我们可以自己写css或者js甚至一些动画特效,但是也有很多开源的组件库帮我们写好了.我们只需要下载并引入即可. vue和element-ui在开发中是比较般配的,也是我们开发中用的很多的,下面就介绍下如何在eue项目中引入element-ui组件库 Element-ui(饿了么ui) element-ui(饿了

  • springboot全局日期格式化的两种方式

    方式一是配置参数 参数配置的方式就是在json序列化的时候,当字段为日期类型的时候的format类型,就相当于在所有日期字段上加了一个注解 @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss"),但是每个字段都加注解太麻烦,所以直接使用全局配置来实现 参数配置也分为两种配置 第一种是yml的配置 spring: jackson: #参数意义: #JsonInclude.Include.A

  • Spring依赖注入(DI)两种方式的示例详解

    目录 一.依赖注入方式 二.setter注入 引用类型 简单类型 三.构造器注入 引用类型 简单类型 参数适配(了解) 四.依赖注入方式选择 一.依赖注入方式 思考:向一个类中传递数据的方式有几种? 普通方法(set方法) 构造方法 思考:依赖注入描述了在容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢? 引用类型 简单类型(基本数据类型与String) 依赖注入方式: setter注入 简单类型 引用类型 构造器注入 简单类型 引用类型 二.setter注

  • Spring Bean属性注入的两种方式详解

    目录 属性注入概念 一.构造器注入 示例1 注意点 二.setter注入 示例2 三.如何选择注入方式 属性注入概念 Spring 属性注入(DI依赖注入)有两种方式:setter注入,构造器注入. 这个注入的属性可以是普通属性(基本数据类型与String等),也可以是一个引用数据类型(主要是对象),或者是一个集合(list.map.set等) 下表是属性注入bean标签中常用的元素 元素名称 描述 constructor-arg 构造器注入.该元素的 index 属性指定构造参数的索引(从 0

  • Linux开机自启动服务两种方式介绍

    目录 rc.local方式 chkconfig方式 rc.local方式 1首先创建一个要自启动的脚本 vi /etc/scripts/createFile.sh #!/bin/bash #开机创建一个文件夹 mkdir /opt/ccc 2.给予执行权限 chmod 777 createFile.sh 3.在/etc/rc.d/rc.local文件中添加脚本的绝对路径 4.给与rc.local执行权限 chmod 777 rc.local 重启服务,发现已经在opt路径下创建了一个ccc的文件

  • springboot创建线程池的两种方式小结

    目录 springboot创建线程池两种方式 1.使用static代码块创建 2.使用@Configuration @bean注解,程序启动时创建 springboot开启线程池 定义线程池 使用 springboot创建线程池两种方式 1.使用static代码块创建 这样的方式创建的好处是当代码用到线程池的时候才会初始化核心线程数 具体代码如下: public class HttpApiThreadPool { /** 获取当前系统的CPU 数目*/ static int cpuNums =

随机推荐