Springboot自动装配之注入DispatcherServlet的实现方法(springboot dispatchservlet)

网友投稿 431 2022-07-29


原理概述

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 = DispatcherServlSCsgOKqRlIet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)

public DispatcherServletRegistrationBean dispatcherServletRegistration(DispatcherServlet dispatcherServlet,

WebMvcProperties webMvcProperties, ObjectProvider 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的关系,相信读了上面的文章会说出一两点;


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java中CyclicBarrier 循环屏障
下一篇:最新springboot中必须要了解的自动装配原理(springboot自动装配原理简言之)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~