RWMutex构建知识体系
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
//我们当前只关注这ConditionalOnWebApplication、ConditionalOnClass注解
//ConditionalOnWebApplication是根据type来判断指定类是否存在
//当前的type是 Type.SERVLET,是来查找org.springframework.web.context.support.GenericWebApplicationContext类是否存在,这个类存在于spring-web中,所以这个条件是true
@ConditionalOnWebApplication(type = Type.SERVLET)
//这个注解上面说过了 ,就是查找指定的类是否存在,这个是查找DispatcherServlet.class是否存在,这里也会返回true
@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";
@Configuration(proxyBeanMethods = false)
//这里还是个条件,通过实现Condition接口,通过matches方法来判断
//DefaultDispatcherServletCondition这个类就在当前这个文件里,matches判断的结果也是true
@Conditional(DefaultDispatcherServletCondition.class)
//ServletRegistration.class这个类存在于tomcat-embed-core里面,这个结果也是true
@ConditionalOnClass(ServletRegistration.class)
//上面两个条件成立,就会执行后续的操作,去遍历内部类和方法
@EnableConfigurationProperties(WebMvcProperties.class)
protected static class DispatcherServletConfiguration {
//beanFactory会创建这个DispatcherServletbean的定义,bean的名字就是dispatcherServlet
@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
DispatcherServlet dispatcherServlet = new DispatcherServlet();
dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());
return 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;
}
}
@Configuration(proxyBeanMethods = false)
//和上面的一样,不说了
@Conditional(DispatcherServletRegistrationCondition.class)
//和上面的一样,不说了
@ConditionalOnClass(ServletRegistration.class)
@EnableConfigurationProperties(WebMvcProperties.class)
//这里会要在查找DispatcherServletConfiguration.class,并执行加载bean定义的流程,这就是上面的类了
@Import(DispatcherServletConfiguration.class)
protected static class DispatcherServletRegistrationConfiguration {
@Bean(name = DEFAULT_DISPATCHER_SERVLET_REGISTRATION_BEAN_NAME)
//ConditionalOnBean查找是否存在指定bean的定义,这个方法要注入参数,需要这个类,当前这里就是上面的dispatcherServlet方法定义的,这里也是存在的
@ConditionalOnBean(value = DispatcherServlet.class, name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
//DispatcherServlet dispatcherServlet这个就是dispatcherServlet这个方法定义的bean,在创建DispatcherServletRegistrationBean这个bean的时候,就会去查找dispatcherServlet是否存在,如果不存在,先创建dispatcherServlet这个bean,再创建DispatcherServletRegistrationBean
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;
}
private void createWebServer() {
WebServer webServer = this.webServer;
ServletContext servletContext = getServletContext();
if (webServer == null && servletContext == null) {
StartupStep createWebServer = this.getApplicationStartup().start("spring.boot.webserver.create");
//上面我们已经看到了这里,factory是TomcatServletWebServerFactory类的一个实例对象
ServletWebServerFactory factory = getWebServerFactory();
//这里还是做个标记,不用关注
createWebServer.tag("factory", factory.getClass().toString());
//这里就是具体创建tomcat了,这里的入参getSelfInitializer()是个lambda表达式,这个后续很重要
this.webServer = factory.getWebServer(getSelfInitializer());
createWebServer.end();
getBeanFactory().registerSingleton("webServerGracefulShutdown",
new WebServerGracefulShutdownLifecycle(this.webServer));
getBeanFactory().registerSingleton("webServerStartStop",
new WebServerStartStopLifecycle(this, this.webServer));
}
else if (servletContext != null) {
try {
getSelfInitializer().onStartup(servletContext);
}
catch (ServletException ex) {
throw new ApplicationContextException("Cannot initialize servlet context", ex);
}
}
initPropertySources();private org.springframework.boot.web.servlet.ServletContextInitializer getSelfInitializer() {
return this::selfInitialize;
}
//是创建webServer的参数
private void selfInitialize(ServletContext servletContext) throws ServletException {
prepareWebApplicationContext(servletContext);
registerApplicationScope(servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}
}
......public WebServer getWebServer(ServletContextInitializer... initializers) {
.......
//上面的入参会在这里传下去
prepareContext(tomcat.getHost(), initializers);
return getTomcatWebServer(tomcat);
}protected void configureContext(Context context, ServletContextInitializer[] initializers) {
//会传递给TomcatStarter,作为构造参数,下面我们去这里看看
TomcatStarter starter = new TomcatStarter(initializers);
......
}这个类不长
class TomcatStarter implements ServletContainerInitializer {
......
TomcatStarter(ServletContextInitializer[] initializers) {
//入参会作为它的成员属性
this.initializers = initializers;
}
@Override
public void onStartup(Set<Class<?>> classes, ServletContext servletContext) throws ServletException {
try {
for (ServletContextInitializer initializer : this.initializers) {
//会在这里调用onStartup方法,这里的入参就是ApplicationContextFacade的对象,里面包装了ApplicationContext,里面再包装了TomcatEmbeddedContext,这要就和tomcat联系起来了,下面的截图就是servletContext的对象结构
initializer.onStartup(servletContext);
}
}
catch (Exception ex) {
......
}private void selfInitialize(ServletContext servletContext) throws ServletException {
//这里是将ApplicationContextFacade设置到当前的servletContext上
prepareWebApplicationContext(servletContext);
//这里是在beanFactory中注册application的scope
registerApplicationScope(servletContext);
//这里还是注册上下文相关的bean
WebApplicationContextUtils.registerEnvironmentBeans(getBeanFactory(), servletContext);
//我们重点来看这里getServletContextInitializerBeans()是定义个一个ServletContextInitializerBeans对象,我们点进去看看
for (ServletContextInitializer beans : getServletContextInitializerBeans()) {
beans.onStartup(servletContext);
}
}