SpringBoot外部servlet容器启动SpringBoot源码学习笔记

外部servlet容器启动SpringBoot原理

org.springframework.web.SpringServletContainerInitializer

	源码:
	@HandlesTypes(WebApplicationInitializer.class)
	public class SpringServletContainerInitializer implements ServletContainerInitializer {
		
		//将所有的这个类型WebApplicationInitializer都传入onStartup的Set<Class<?>>里,为这些SpringServletContainerInitializer类型的类创建实例
		//webAppInitializerClasses感兴趣的所有类
		@Override
		public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
				throws ServletException {

			List<WebApplicationInitializer> initializers = new LinkedList<>();

			if (webAppInitializerClasses != null) {
				for (Class<?> waiClass : webAppInitializerClasses) {
					// Be defensive: Some servlet containers provide us with invalid classes,
					// no matter what @HandlesTypes says...
					//判断waiClass是不是接口,抽象的
					f (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
							WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
						try {
							//不是接口,抽象的就创建对象
							initializers.add((WebApplicationInitializer)
									ReflectionUtils.accessibleConstructor(waiClass).newInstance());
						}
						catch (Throwable ex) {
							throw new ServletException("Failed to instantiate WebApplicationInitializer class", ex);
						}
					}
				}
			}

			if (initializers.isEmpty()) {
				servletContext.log("No Spring WebApplicationInitializer types detected on classpath");
				return;
			}

			servletContext.log(initializers.size() + " Spring WebApplicationInitializers detected on classpath");
			AnnotationAwareOrderComparator.sort(initializers);
			for (WebApplicationInitializer initializer : initializers) {
				initializer.onStartup(servletContext);
			}
		}
	}

WebApplicationInitializer

		源码:
		public interface WebApplicationInitializer {

			void onStartup(ServletContext servletContext) throws ServletException;

		}
public class ServletInitializer extends SpringBootServletInitializer {

	@Override
	protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
		//传入SpringBoot应用的主程序
		return application.sources(SpringBoot04WebJspApplication.class);
	}
}

SpringBootServletInitializer

	源码:
	public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
		@Override
		public void onStartup(ServletContext servletContext) throws ServletException {
			// Logger initialization is deferred in case an ordered
			// LogServletContextInitializer is being used
			this.logger = LogFactory.getLog(getClass());
			//创建创建容器
			WebApplicationContext rootAppContext = createRootApplicationContext(servletContext);
			if (rootAppContext != null) {
				servletContext.addListener(new ContextLoaderListener(rootAppContext) {
					@Override
					public void contextInitialized(ServletContextEvent event) {
						// no-op because the application context is already initialized
					}
				});
			}
			else {
				this.logger.debug("No ContextLoaderListener registered, as createRootApplicationContext() did not "
						+ "return an application context");
			}
		}
		protected WebApplicationContext createRootApplicationContext(ServletContext servletContext) {
			//1.创建应用构建器SpringApplicationBuilder
			SpringApplicationBuilder builder = createSpringApplicationBuilder();
			//设置主类
			builder.main(getClass());
			ApplicationContext parent = getExistingRootWebApplicationContext(servletContext);
			if (parent != null) {
				this.logger.info("Root context already created (using as parent).");
				servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, null);
				builder.initializers(new ParentContextApplicationContextInitializer(parent));
			}
			builder.initializers(new ServletContextApplicationContextInitializer(servletContext));
			builder.contextClass(AnnotationConfigServletWebServerApplicationContext.class);
			//调用configure方法,子类重写了这个方法,将SpringBoot的主程序类传入进来
			builder = configure(builder);
			builder.listeners(new WebEnvironmentPropertySourceInitializer(servletContext));
			//使用builder创建一个Spring应用
			SpringApplication application = builder.build();
			if (application.getAllSources().isEmpty()
					&& MergedAnnotations.from(getClass(), SearchStrategy.TYPE_HIERARCHY).isPresent(Configuration.class)) {
				application.addPrimarySources(Collections.singleton(getClass()));
			}
			Assert.state(!application.getAllSources().isEmpty(),
					"No SpringApplication sources have been defined. Either override the "
							+ "configure method or add an @Configuration annotation");
			// Ensure error pages are registered
			if (this.registerErrorPageFilter) {
				application.addPrimarySources(Collections.singleton(ErrorPageFilterConfiguration.class));
			}
			//启动Spring应用
			return run(application);
		}
	}

run()

		源码:
		protected WebApplicationContext run(SpringApplication application) {
			return (WebApplicationContext) application.run();
		}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值