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学习笔记—— SpringBoot和微服务架构
Day695.Spring Boot如何使用内嵌式的Tomcat和Jetty -深入拆解 Tomcat & Jetty
springboot去除内嵌tomcat和打包在tomcat中运行需要做的步骤