Spring源码-Springboot使用内置tomcat配置DispatcherServlet


前言

基于版本2.0.5.RELEASE

springboot使用主启动类启动,DispatcherServlet怎么配置到内置tomcat的?

在主启动类启动时会先生成主启动类的beanDefinition,然后解析主启动类上的注解,其中有EnableAutoConfiguration注解,EnableAutoConfiguration上有@Import注解,解析@Import注解的时候会使用SPI机制将所有spring.factories内的配置类读取,并生成beanDefinition,其中一个配置类DispatcherServletAutoConfiguration将DispatcherServlet注入spring容器,将DispatcherServletRegistrationBean注入spring容器,而DispatcherServletRegistrationBean间接实现了ServletContextInitializer接口,最终会被调用,将DispatcherServlet设置到ServletContext里,并设置loadOnStartup和urlMapping属性

在什么阶段设置的?
spring上下文执行refresh方法内的onRefresh方法的时候


一、ServletWebServerApplicationContext.onfresh

@Override
	protected void onRefresh() {
		super.onRefresh();
		try {
			createWebServer();
		}
		catch (Throwable ex) {
			throw new ApplicationContextException("Unable to start web server", ex);
		}
	}
	private void createWebServer() {
		WebServer webServer = this.webServer;
		ServletContext servletContext = getServletContext();
		if (webServer == null && servletContext == null) {
			ServletWebServerFactory factory = getWebServerFactory();
			 // 调用spring容器里所有ServletContextInitializer接口实现类的onStartup方法
             // 其中有DispatcherServletAutoConfiguration配置类配置的DispatcherServletRegistrationBean类
             // 配置DispatcherServlet到tomcat上下文
			this.webServer = factory.getWebServer(getSelfInitializer());
		}
		else if (servletContext != null) {
			try {
				getSelfInitializer().onStartup(servletContext);
			}
			catch (ServletException ex) {
				throw new ApplicationContextException("Cannot initialize servlet context", ex);
			}
		}
		initPropertySources();
	}

二、RegistrationBean

@Override
	public final void onStartup(ServletContext servletContext) throws ServletException {
		String description = getDescription();
		if (!isEnabled()) {
			logger.info(StringUtils.capitalize(description) + " was not registered (disabled)");
			return;
		}
		register(description, servletContext);
	}

三、DynamicRegistrationBean

	@Override
	protected final void register(String description, ServletContext servletContext) {
		D registration = addRegistration(description, servletContext);
		if (registration == null) {
			logger.info(
					StringUtils.capitalize(description) + " was not registered " + "(possibly already registered?)");
			return;
		}
		configure(registration);
	}

四、ServletRegistrationBean

    @Override
	protected ServletRegistration.Dynamic addRegistration(String description, ServletContext servletContext) {
		String name = getServletName();
		return servletContext.addServlet(name, this.servlet);
	}
    @Override
	protected void configure(ServletRegistration.Dynamic registration) {
		super.configure(registration);
		String[] urlMapping = StringUtils.toStringArray(this.urlMappings);
		if (urlMapping.length == 0 && this.alwaysMapUrl) {
			urlMapping = DEFAULT_MAPPINGS;
		}
        // 配置servlet相关的属性(loadonStartup、urlMapping)
		if (!ObjectUtils.isEmpty(urlMapping)) {
			registration.addMapping(urlMapping);
		}
		registration.setLoadOnStartup(this.loadOnStartup);
		if (this.multipartConfig != null) {
			registration.setMultipartConfig(this.multipartConfig);
		}
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值