springBoot学习笔记内嵌tomcat和springmvc

Posted 拐柒

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springBoot学习笔记内嵌tomcat和springmvc相关的知识,希望对你有一定的参考价值。

springBoot学习笔记(五)内嵌tomcat和springmvc

源码剖析

内嵌tomcat

Spring Boot默认支持Tomcat,Jetty,和Undertow作为底层容器。
而Spring Boot默认使用Tomcat,一旦引入spring-boot-starter-web模块,就默认使用Tomcat容器。

tomcat自动配置类ServletWebServerFactoryAutoConfiguration

入该类,里面也通过@Import注解将EmbeddedTomcat、EmbeddedJetty、
EmbeddedUndertow等嵌入式容器类加载进来了,springboot默认是启动嵌入式tomcat容器,
如果要改变启动jetty或者undertow容器,需在pom文件中去设置。

SpringBoot启动内置tomcat流程

1、进入springboot启动类SpringBootApplication的源码,
2、@EnableAutoConfiguration,进入注解,如下图
**
**
3、selectImport()方法,在该方法中调用了
getAutoConfigurationEntry()方法,在之中又调用了getCandidateConfigurations()方法。该方法就是去META-INF/spring.factory配置文件中加载相关配置类
4、找到tomcat加载的配置类ServletWebServerFactoryAutoConfiguration

5、该类通过@Import注解将EmbeddedTomcat、EmbeddedJetty、
EmbeddedUndertow等嵌入式容器类加载。

6、进入EmbeddedTomcat类,

7、进入TomcatServletWebServerFactory类中,找到getWebServer方法,


在返回值调用的方法中进行了tomcat的启动,调用了tomcat.start();

getWebServer方法的调用

1、执行SpringApplication.run(xxxaApplication.class, args)最终调用同名run方法,

2、最终调用org.springframework.context.support.AbstractApplicationContext#refresh

在onRefresh方法中会调用到ServletWebServerApplicationContext中的createWebServer()
3、createWebServer


4、createWebServer其中调用了getWebServer


则在此处调用了tomcat的创建。

springmvc

Servlet3.0规范中规定,要添加一个Servlet,除了采用xml配置的方式,还有一种通过代码的方式,

servletContext.addServlet(name, this.servlet);

就是说,如果我们能动态往web容器中添加一个我们构造好的 DispatcherServlet 对象,就实现自动装配SpringMVC了

自动配置(一)自动配置DispatcherServlet和DispatcherServletRegistry

springboot的自动配置基于SPI机制,实现自动配置的核心要点就是添加一个自动配置的类,SpringBoot MVC的自动配置自然也是相同原理

DispatcherServletAutoConfiguration自动配置类

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration 

1、这是一个配置类,将会被spring给解析
2、@ConditionalOnWebApplication意味着当时一个web项目,且是Servlet项目的时候才会被解析。
3、@ConditionalOnClass指明DispatcherServlet这个核心类必须存在才解析该类。
4、@AutoConfigureAfter指明在ServletWebServerFactoryAutoConfiguration这个类之后再解析,设定了一个顺序。
DispatcherServletAutoConfiguration类主要包含了两个内部类,分别是
1、DispatcherServletConfiguration
2、DispatcherServletRegistrationConfiguration

DispatcherServletConfiguration

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

DispatcherServlet类(DispatcherServletConfiguration内部类)

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

DispatcherServletRegistrationConfiguration类

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

DispatcherServletRegistrationBean(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;
		

springboot mvc的自动配置类是DispatcherServletAutoConfigration,主要做了两件事:
1)配置DispatcherServlet
2)配置DispatcherServlet的注册Bean(DispatcherServletRegistrationBean)

自动配置(二)注册DispatcherServlet到ServletContext

注册DispatcherServlet流程

1、RegistrationBean实现ServletContextInitializer接口,重写onstartup方法
2、DynamicRegistrationBean实现RegistrationBean中的抽象方法register
3、ServletRegistrationBean实现DynamicRegistrationBean中的抽象方法addRegistration,在该方法中将DispatcherServlet添加到了servletContext。

以上是关于springBoot学习笔记内嵌tomcat和springmvc的主要内容,如果未能解决你的问题,请参考以下文章

springboot配置tomcat内存

SpringBoot学习笔记—— SpringBoot和微服务架构

Day695.Spring Boot如何使用内嵌式的Tomcat和Jetty -深入拆解 Tomcat & Jetty

springboot去除内嵌tomcat和打包在tomcat中运行需要做的步骤

SpringBoot与Tomcat的启动(内嵌Tomcat)

SpringBoot如何使用内嵌Tomcat