Springboot自动装配之注入DispatcherServlet的实现方法

原理概述

Springboot向外界提供web服务,底层依赖了springframework中的web模块(包含但不限于spring mvc核心类DispatcherServlet)来实现

那么springboot在什么时机向容器注入DispatcherServlet这个核心类的呢
注入的流程还是遵循了自动装配流程,在springboot框架里默认提供了该自动装配的支持

在jar包里的spring.factories文件里有个 org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration配置

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {
	/*
	 * The bean name for a DispatcherServlet that will be mapped to the root URL "/"
	 */
	public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
	/*
	 * The bean name for a ServletRegistrationBean for the DispatcherServlet "/"
	 *
	public static final String DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME = "dispatcherServletRegistration";
	// ... 省略代码
	}

在DispatcherServletAutoConfiguration中有两个内部类(配置类) DispatcherServletConfiguration、DispatcherServletRegistrationConfiguration和两个对应的Condition类DefaultDispatcherServletCondition、DispatcherServletRegistrationCondition

DispatcherServletConfiguration

DispatcherServletConfiguration是DispatcherServletAutoConfiguration 的一个内部类,并被 @Configuration标注,会被容器自动扫描到;其有两个方法: 1、dispatcherServlet;2、multipartResolver

	@Configuration(proxyBeanMethods = false)
	@Conditional(DefaultDispatcherServletCondition.class)
	@ConditionalOnClass(ServletRegistration.class)
	@EnableConfigurationProperties({ HttpProperties.class, WebMvcProperties.class })
	protected static class DispatcherServletConfiguration {

// @A
		@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
		public DispatcherServlet dispatcherServlet(HttpProperties httpProperties, WebMvcProperties webMvcProperties) {
			DispatcherServlet dispatcherServlet = new DispatcherServlet();
			dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
			dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
			dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
			dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
			dispatcherServlet.setEnableLoggingRequestDetails(httpProperties.isLogRequestDetails());
			return dispatcherServlet;
		}

// @B
		@Bean
		@ConditionalOnBean(MultipartResolver.class)
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}
	}

@A:

  • @Configuration(proxyBeanMethods = false):配置类采用Lite模式
  • @Conditional(DefaultDispatcherServletCondition.class):根据DefaultDispatcherServletCondition类返回值计算是否要注入,主要逻辑是检验Spring容器中是否已经存在一个名字为"dispatcherServlet"的DispatcherServlet
  • @ConditionalOnClass(ServletRegistration.class):容器中必须要有ServletRegistration类
  • @EnableConfigurationProperties({ HttpProperties.class, WebMvcProperties.class }):加载HttpProperties和WebMvcProperties

@B:注入 MultipartResolver 解析类

DispatcherServletRegistrationConfiguration

该类注入的逻辑与DispatcherServletConfiguration 相同,只不过在类上注解了 @Import(DispatcherServletConfiguration.class)那么这两个类定义就有了先后顺序

@Configuration(proxyBeanMethods = false)
	@Conditional(DispatcherServletRegistrationCondition.class)
	@ConditionalOnClass(ServletRegistration.class)
	@EnableConfigurationProperties(WebMvcProperties.class)
	@Import(DispatcherServletConfiguration.class) //@A
	protected static class DispatcherServletRegistrationConfiguration {

		@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;
		}
	}

其中,DispatcherServletRegistrationBean继承自ServletRegistrationBean,主要为DispatcherServlet提供服务。DispatcherServletRegistrationBean和DispatcherServlet都提供了注册Servlet并公开DispatcherServletPath信息的功能

面试点

spring mvc和spring boot的关系,相信读了上面的文章会说出一两点;

到此这篇关于Springboot自动装配之注入DispatcherServlet的文章就介绍到这了,更多相关Springboot注入DispatcherServlet内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 深入浅析SpringBoot中的自动装配

    SpringBoot的自动装配是拆箱即用的基础,也是微服务化的前提.这次主要的议题是,来看看它是怎么样实现的,我们透过源代码来把握自动装配的来龙去脉. 一.自动装配过程分析 1.1.关于@SpringBootApplication 我们在编写SpringBoot项目时,@SpringBootApplication是最常见的注解了,我们可以看一下源代码: /* * Copyright 2012-2017 the original author or authors. * * Licensed un

  • SpringBoot启动及自动装配原理过程详解

    一.servlet2(老spring-mvc) 配置文件: web.xml:主要配置项目启动项 application-context.xml:主要配置项目包扫描.各种bean.事务管理 springMVC.xml:主要配置controller包扫描.视图解析器.参数解析器 启动过程: 每一个spring项目启动时都需要初始化spring-context,对于非web项目可以在程序main方法中触发这个context的初始化过程. 由于web项目的启动入口在容器,所以开发者不能直接触发sprin

  • Springboot自动装配之注入DispatcherServlet的实现方法

    原理概述 Springboot向外界提供web服务,底层依赖了springframework中的web模块(包含但不限于spring mvc核心类DispatcherServlet)来实现 那么springboot在什么时机向容器注入DispatcherServlet这个核心类的呢注入的流程还是遵循了自动装配流程,在springboot框架里默认提供了该自动装配的支持 在jar包里的spring.factories文件里有个 org.springframework.boot.autoconfig

  • springboot自动装配原理初识

    运行原理 为了研究,我们正常从父项目的pom.xml开始进行研究. pom.xml 父依赖 spring-boot-starter-parent主要用来管理项目的资源过滤和插件 <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.5.RELEASE<

  • SpringBoot自动装配Condition的实现方式

    目录 1. 简介 2. 定义 2.1 @Conditional 2.2 Condition 3. 使用说明 3.1 创建项目 3.2 测试 3.3 小结 4. 改进 4.1 创建注解 4.2 修改UserCondition 5. Spring内置条件注解 1. 简介 @Conditional注解在Spring4.0中引入,其主要作用就是判断条件是否满足,从而决定是否初始化并向容器注册Bean. 2. 定义 2.1 @Conditional @Conditional注解定义如下:其内部只有一个参数

  • 深入了解Java SpringBoot自动装配原理

    目录 自动装配原理 SpringBootApplication EnableAutoConfiguration AutoConfigurationImportSelector 总结 在使用springboot时,很多配置我们都没有做,都是springboot在帮我们完成,这很大一部分归功于springboot自动装配,那springboot的自动装配的原理是怎么实现的呢? 自动装配原理 springboot 版本:2.4.3 SpringBootApplication springboot启动类

  • SpringBoot 自动装配的原理详解分析

    目录 前言 自动装配案例 自动装配分析 自动装配总结 前言 关于 ​​SpringBoot​​​ 的自动装配功能,相信是每一个 ​​Java​​ 程序员天天都会用到的一个功能,但是它究竟是如何实现的呢?今天阿粉来带大家看一下. 自动装配案例 首先我们通过一个案例来看一下自动装配的效果,创建一个 ​​SpringBoot​​ 的项目,在 ​​pom​​ 文件中加入下面的依赖. <dependency> <groupId>org.springframework.boot</gro

  • SpringBoot自动装配原理详解

    首先对于一个SpringBoot工程来说,最明显的标志的就是 @SpringBootApplication它标记了这是一个SpringBoot工程,所以今天的 SpringBoot自动装配原理也就是从它开始说起. 自动装配流程 首先我们来看下@SpringBootApplication 这个注解的背后又有什么玄机呢,我们按下 ctrl + 鼠标左键,轻轻的点一下,此时见证奇迹的时刻.. 我们看到如下优雅的代码: 这其中有两个比较容易引起我们注意的地方,一个是@SpringBootConfigur

  • 浅谈springboot自动装配原理

    一.SpringBootApplication @Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @SpringBootConfiguration @EnableAutoConfiguration @ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFi

  • SpringBoot自动装配原理小结

    约定优于配置(Convention Over Configuration)是一种软件设计范式,目的在于减少配置的数量或者降低理解难度,从而提升开发效率. 先总结一下结论: springboot通过spring.factories能把main方法所在类路径以外的bean自动加载,其目的就是为了帮助自动配置bean,减轻配置量 springboot autoconfig的一些实验 一个springboot工程,springbootautoconfig.test.config这个包和启动类的包不再同一

  • springboot自动装配的源码与流程图

    前言 在使用SpringBoot开发项目中,遇到一些 XXX-XXX-starter,例如mybatis-plus-boot-starter,这些包总是能够自动进行配置, 减少了开发人员配置一些项目配置的时间,让开发者拥有更多的时间用于开发的任务上面.下面从源码开始. 正文 SpringBoot版本:2.5.3 从@SpringBootApplication进入@EnableAutoConfiguration 然后进入AutoConfigurationImportSelector @Target

  • Java SpringBoot自动装配原理详解及源码注释

    目录 一.pom.xml文件 1.父依赖 2.启动器: 二.主程序: 剖析源码注解: 三.结论: 一.pom.xml文件 1.父依赖 主要是依赖一个父项目,管理项目的资源过滤以及插件! 资源过滤已经配置好了,无需再自己配置 在pom.xml中有个父依赖:spring-boot-dependencies是SpringBoot的版本控制中心! 因为有这些版本仓库,我们在写或者引入一些springboot依赖的时候,不需要指定版本! 2.启动器: 启动器也就是Springboot的启动场景; 比如sp

随机推荐