SpringBoot如何省去Web.xml?

1、Web.xml 是Spring应用和Servlet联系的中介

Servlet容器启动后,Servlet容器会根据web.xml中的配置初始化Spring容器。

2、Servlet3.0奠定了SpringBoot 零xml配置的基础

在Servlet3.0容器初始化时会调用jar包META-INF/services/javax.servlet.ServletContainerInitializer中指定的类的实现,先看看ServletContainerInitializer接口:

public interface ServletContainerInitializer {
    void onStartup(Set<Class<?>> c, ServletContext ctx) throws ServletException;
}

而作为Servlet3.0容器之一的Tomcat,当然就会调用SpringWeb jar包下的实现,如下。
在这里插入图片描述
再看看SpringWeb的类SpringServletContainerInitializer

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {

	@Override
	public void onStartup(Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {

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

		if (webAppInitializerClasses != null) {
			for (Class<?> waiClass : webAppInitializerClasses) {
				// Be defensive: Some servlet containers provide us with invalid classes,
				// no matter what @HandlesTypes says...
				if (!waiClass.isInterface() && !Modifier.isAbstract(waiClass.getModifiers()) &&
						WebApplicationInitializer.class.isAssignableFrom(waiClass)) {
					try {
						initializers.add((WebApplicationInitializer) 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);
		}
	}

SpringServletContainerInitializer的类添加了@HandlesTypes注解,在@HandlesTypes注解中可以指定的感兴趣的类(如WebApplicationInitializer.class),就可以在onStartup()通过方法参数传入感兴趣的类(如WebApplicationInitializer)的所有的实现类,而这些实现类可以理解为具体实现了web.xml的功能,当然也可以有其他的用途)。下图是WebApplicationInitializer的几个具体的实现类:
在这里插入图片描述

上图的3个实现类,由类名就可以猜测到和web.xml配置的几个组件ContextLoaderListener、DispatcherServlet相关,这几个组件就是由这3个实现类创建的。由此,一言以蔽之:javax.servlet.ServletContainerInitializer中的实现类替代了web.xml的作用!

最后,从全局看下调用过程如下:

Servlet3.0容器(Tomcat)
	-> SpringServletContainerInitializer.onStartup()
		->WebApplicationInitializer.onStartup()
			->createRootApplicationContext(Spring容器)

SpringBoot如何省去Web.xml
而Tomcat又是具体如何启动SpringWeb项目的,请看《Tomcat源码阅读—如何启动SpringWeb项目》
如果想了解ContextLoaderListener、DispatcherServlet这两个组件是如何加载的,请看另一篇文章:《Springmvc源码阅读-父子容器的加载》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值