说在前面
前期回顾
sharding-jdbc源码解析 更新完毕
spring源码解析 更新完毕
spring-mvc源码解析 更新完毕
spring-tx源码解析 更新完毕
spring-boot源码解析 更新完毕
rocketmq源码解析 更新完毕
dubbbo源码解析 更新完毕
netty源码解析 更新完毕
spring源码架构更新完毕
spring-mvc源码架构更新完毕
springboot源码架构更新中
github https://github.com/tianheframe
sharding-jdbc源码解析 更新完毕
rocketmq源码解析 更新完毕
seata 源码解析 更新完毕
dubbo 源码解析 更新完毕
netty 源码解析 更新完毕
源码解析
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration Spring DispatcherServlet的自动配置。应该适用于已经存在嵌入式servlet容器的独立应用程序,也适用于使用SpringBootServletInitializer的可部署应用程序。
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)@Configuration@ConditionalOnWebApplication@ConditionalOnClass(DispatcherServlet.class)@AutoConfigureAfter(EmbeddedServletContainerAutoConfiguration.class)public class DispatcherServletAutoConfiguration {
监测到DispatcherServlet calss类,在配置EmbeddedServletContainerAutoConfiguration之后配置该类
public static final String DEFAULT_DISPATCHER_SERVLET_BEAN_NAME = "dispatcherServlet";
默认转发servlet是dispatcherServlet
@Configuration @Conditional(DefaultDispatcherServletCondition.class) @ConditionalOnClass(ServletRegistration.class) @EnableConfigurationProperties(WebMvcProperties.class) protected static class DispatcherServletConfiguration {
执行DefaultDispatcherServletCondition条件判断,加载到ServletRegistration class类,加载WebMvcProperties配置文件
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition#getMatchOutcome
@Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) { ConditionMessage.Builder message = ConditionMessage .forCondition("Default DispatcherServlet");// 获取BeanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();// 根据类型从beanFactory找出DispatcherServlet实现类的beanNames List dispatchServletBeans = Arrays.asList(beanFactory .getBeanNamesForType(DispatcherServlet.class, false, false)); if (dispatchServletBeans.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) { return ConditionOutcome.noMatch(message.found("dispatcher servlet bean") .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)); } if (beanFactory.containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) { return ConditionOutcome .noMatch(message.found("non dispatcher servlet bean") .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)); } if (dispatchServletBeans.isEmpty()) { return ConditionOutcome .match(message.didNotFind("dispatcher servlet beans").atAll()); } return ConditionOutcome.match(message .found("dispatcher servlet bean", "dispatcher servlet beans") .items(Style.QUOTE, dispatchServletBeans) .append("and none is named " + DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)); }
从BeanFactory中监测org.springframework.web.servlet.DispatcherServlet类型的bean,组装监测信息。
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public DispatcherServlet dispatcherServlet() { DispatcherServlet dispatcherServlet = new DispatcherServlet(); dispatcherServlet.setDispatchOptionsRequest( this.webMvcProperties.isDispatchOptionsRequest()); dispatcherServlet.setDispatchTraceRequest( this.webMvcProperties.isDispatchTraceRequest()); dispatcherServlet.setThrowExceptionIfNoHandlerFound( this.webMvcProperties.isThrowExceptionIfNoHandlerFound()); return dispatcherServlet; }
初始化dispatcherServlet
@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; }
监测MultipartResolver类型的bean,没检测到multipartResolver名称的bean,创建MultipartResolver
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DispatcherServletRegistrationConfiguration
@Configuration @Conditional(DispatcherServletRegistrationCondition.class) @ConditionalOnClass(ServletRegistration.class) @EnableConfigurationProperties(WebMvcProperties.class) @Import(DispatcherServletConfiguration.class) protected static class DispatcherServletRegistrationConfiguration {
执行DispatcherServletRegistrationCondition类监测逻辑,监测到ServletRegistration这个bean,加载WebMvcProperties配置,引入DispatcherServletConfiguration的BeanDefinition
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition
@Override public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {// 获取BeanFactory ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();// 检查dispatcherServlet并组装匹配结果 ConditionOutcome outcome = checkDefaultDispatcherName(beanFactory); if (!outcome.isMatch()) { return outcome; }// 检查dispatcherServletRegistration return checkServletRegistration(beanFactory); }
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition#checkDefaultDispatcherName
private ConditionOutcome checkDefaultDispatcherName( ConfigurableListableBeanFactory beanFactory) {// 获取beanFactory中DispatcherServlet类型的beanNames List servlets = Arrays.asList(beanFactory .getBeanNamesForType(DispatcherServlet.class, false, false));// beanFactory中是否包含dispatcherServlet这个bean boolean containsDispatcherBean = beanFactory .containsBean(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME);// BeanFactory中包含dispatcherServlet这个bean,不包含dispatcherServlet这个beanName if (containsDispatcherBean && !servlets.contains(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)) {// 组装匹配结果 return ConditionOutcome .noMatch(startMessage().found("non dispatcher servlet") .items(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)); } return ConditionOutcome.match(); }
org.springframework.boot.autoconfigure.web.DispatcherServletAutoConfiguration.DispatcherServletRegistrationCondition#checkServletRegistration
private ConditionOutcome checkServletRegistration( ConfigurableListableBeanFactory beanFactory) { ConditionMessage.Builder message = startMessage();// 从beanFactory中查找ServletRegistrationBean的实现类的beanNames List registrations = Arrays.asList(beanFactory .getBeanNamesForType(ServletRegistrationBean.class, false, false));// BeanFactory中是够包含dispatcherServletRegistration bean boolean containsDispatcherRegistrationBean = beanFactory .containsBean(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME);// 组装匹配结果 if (registrations.isEmpty()) { if (containsDispatcherRegistrationBean) { return ConditionOutcome .noMatch(message.found("non servlet registration bean").items( DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)); } return ConditionOutcome .match(message.didNotFind("servlet registration bean").atAll()); } if (registrations .contains(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)) { return ConditionOutcome.noMatch(message.found("servlet registration bean") .items(DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)); } if (containsDispatcherRegistrationBean) { return ConditionOutcome .noMatch(message.found("non servlet registration bean").items( DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)); } return ConditionOutcome.match(message.found("servlet registration beans") .items(Style.QUOTE, registrations).append("and none is named " + DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)); }
private final ServerProperties serverProperties;
serverProperties
org.springframework.boot.autoconfigure.web.ServerProperties
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)public class ServerProperties implements EmbeddedServletContainerCustomizer, EnvironmentAware, Ordered {
文件属性名以server开始
private Integer port;
服务端口
private String contextPath;
servlet上下文路径
private String servletPath = "/";
servlet路径
private final Map<String, String> contextParameters = new HashMap<String, String>();
servletContext参数
private Integer connectionTimeout;
连接器在关闭连接之前等待另一个HTTP请求的时间(以毫秒为单位)。未设置时,将使用连接器容器特定的缺省值。使用-1值表示没有超时(即无限超时)。
private final Tomcat tomcat = new Tomcat();
tomcat
org.springframework.boot.autoconfigure.web.ServerProperties.Tomcat
private File basedir;
tomcat基础目录
private int backgroundProcessorDelay = 10;
调用backgroundProcess方法之间的延迟(以秒为单位)。
private int maxThreads = 200;
最大线程数
private int minSpareThreads = 10;
最小工作线程数
private int maxHttpPostSize = 2097152;
HTTP post内容的最大字节数。
private int maxConnections = 10000;
服务器将在任何给定时间接受和处理的最大连接数。一旦达到限制,操作系统仍然可以基于“acceptCount”属性接受连接。
private int acceptCount = 100;
使用所有可能的请求处理线程时传入连接请求的最大队列长度。
private final Jetty jetty = new Jetty();
jetty
org.springframework.boot.autoconfigure.web.ServerProperties.Jetty
private int maxHttpPostSize = 200000;
HTTP post或put内容的最大字节数。
private Integer acceptors = -1;
要使用的接受器线程数。当值为-1(默认值)时,接受器的数量来自操作环境。
private Integer selectors = -1;
要使用的选择器线程数。当值为-1(默认值)时,选择器的数量来自操作环境。
private Session session = new Session();
session
org.springframework.boot.autoconfigure.web.ServerProperties.Session
private Integer timeout;
session超时时间
private File storeDir;
存储路径
@Override public void customize(ConfigurableEmbeddedServletContainer container) { if (getPort() != null) { container.setPort(getPort()); } if (getAddress() != null) { container.setAddress(getAddress()); } if (getContextPath() != null) { container.setContextPath(getContextPath()); } if (getDisplayName() != null) { container.setDisplayName(getDisplayName()); } if (getSession().getTimeout() != null) { container.setSessionTimeout(getSession().getTimeout()); } container.setPersistSession(getSession().isPersistent()); container.setSessionStoreDir(getSession().getStoreDir()); if (getSsl() != null) { container.setSsl(getSsl()); } if (getJspServlet() != null) { container.setJspServlet(getJspServlet()); } if (getCompression() != null) { container.setCompression(getCompression()); } container.setServerHeader(getServerHeader()); if (container instanceof TomcatEmbeddedServletContainerFactory) { getTomcat().customizeTomcat(this, (TomcatEmbeddedServletContainerFactory) container); } if (container instanceof JettyEmbeddedServletContainerFactory) { getJetty().customizeJetty(this, (JettyEmbeddedServletContainerFactory) container); } if (container instanceof UndertowEmbeddedServletContainerFactory) { getUndertow().customizeUndertow(this, (UndertowEmbeddedServletContainerFactory) container); } container.addInitializers(new SessionConfiguringInitializer(this.session)); container.addInitializers(new InitParameterConfiguringServletContextInitializer( getContextParameters())); }
定制化ConfigurableEmbeddedServletContainer
public String getServletMapping() { if (this.servletPath.equals("") || this.servletPath.equals("/")) { return "/"; } if (this.servletPath.contains("*")) { return this.servletPath; } if (this.servletPath.endsWith("/")) { return this.servletPath + "*"; } return this.servletPath + "/*"; }
设置servletPath
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME) @ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME) public ServletRegistrationBean dispatcherServletRegistration( DispatcherServlet dispatcherServlet) {// mapping默认是/* ServletRegistrationBean registration = new ServletRegistrationBean( dispatcherServlet, this.serverProperties.getServletMapping()); registration.setName(DEFAULT_DISPATCHER_SERVLET_BEAN_NAME); registration.setLoadOnStartup( this.webMvcProperties.getServlet().getLoadOnStartup()); if (this.multipartConfig != null) { registration.setMultipartConfig(this.multipartConfig); } return registration; }
如果检测到DispatcherServlet bean就初始化dispatcherServletRegistration