SpringMVC注解方式的启动过程

生成式深度学习(第二版)-第一章-Conda环境下TensorFlow和Keras的安装和配置 按照书籍中的代码运行提示,需要配置Docker。个人的机器上正好有 conda4.14.0,索性就在本地环境进行配置。 阅读详情

1.Servlet容器启动

1.1 原理

在Servlet3.0之前,配置Servlet容器的上下文,需要在WEB-INF/web.xml文件配置,而在Servlet3.0之后,提供了一种免Web.xml配置的方式,它提供了ServletContainerInitializer接口,容器会在启动的时候查找类中实现ServletContainerInitializer接口的类,然后在ServletContainerInitializer#onStartup方法进行配置即可。Springmvc以注解方式配置Servlet容器就是依靠这个接口,实现类为SpringServletContainerInitializer。

ServletContainerInitializer源码

public interface ServletContainerInitializer {

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

1.2 ServletContainerInitializer的使用

  1. 自定义一个类实现ServletContainerInitializer接口,并在onStartup方法中配置Servlet容器
  2. 这个类必须在jar包中的MATE-INF/services/javax.servlet.ServletContainerInitializer文件中进行声明,文件的内容就是这个实现类的全类名
    在这里插入图片描述

SpringMvc提供了一个默认实现SpringServletContainerInitializer类

@HandlesTypes(WebApplicationInitializer.class)
public class SpringServletContainerInitializer implements ServletContainerInitializer {
    
    @Override
	public void onStartup(@Nullable Set<Class<?>> webAppInitializerClasses, ServletContext servletContext)
			throws ServletException {
		// 忽略其他代码
		.......
		for (WebApplicationInitializer initializer : initializers) {
			initializer.onStartup(servletContext);
		}
	}
}

其中可以看到SpringServletContainerInitializer标注了@HandlesTypes注解,它的目的是,在容器中扫描到所有属于WebApplicationInitializer类型的类,放到数组中,并且传递给onStartup的第一个参数webAppInitializerClasses

1.3 WebApplicationInitializer

上面说到SpringServletContainerInitializer#onStartup方法第一个参数是WebApplicationInitializer类型数组,SpringServletContainerInitializer配置容器的任务就是委托给它们进行处理,调用WebApplicationInitializer#onStartup方法,SpringMvc提供了一个实现该接口方法的抽象类AbstractAnnotationConfigDispatcherServletInitializer,它的类关系图如下
在这里插入图片描述
它的父类AbstractDispatcherServletInitializer 实现了onStartup方法

public abstract class AbstractDispatcherServletInitializer extends AbstractContextLoaderInitializer {
	.......
	
	public void onStartup(ServletContext servletContext) throws ServletException {
		// 调用父类方法,主要创建父容器
        super.onStartup(servletContext);
        //创建SpringMvc容器,创建DispatcherServlet
        this.registerDispatcherServlet(servletContext);
    }
   .......
}

2 Web父容器

创建Web父容器时调用了父类AbstractContextLoaderInitializer #onStartup方法,做了2件事情

1.创建父容器
2.注册ContextLoaderListener到Servlet容器中

2.1 创建Web父容器

除非配置了父类配置类,不然不会创建父容器,这里只做介绍,不深究

public abstract class AbstractContextLoaderInitializer implements WebApplicationInitializer {
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		registerContextLoaderListener(servletContext);
	}
	
	protected void registerContextLoaderListener(ServletContext servletContext) {
		// 如果配置了父容器的配置类,创建父容器,默认为null
		WebApplicationContext rootAppContext = createRootApplicationContext();
		if (rootAppContext != null) {
			// 创建ContextLoaderListener
			ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
			listener.setContextInitializers(getRootApplicationContextInitializers());
			// 添加监听器到Servlet中
			servletContext.addListener(listener);
		}
		else {
			logger.debug("No ContextLoaderListener registered, as " +
					"createRootApplicationContext() did not return an application context");
		}
	}
}

createRootApplicationContext方法主要是创建父容器,默认为null,不会创建,方法的实现在AbstractAnnotationConfigDispatcherServletInitializer#createRootApplicationContext

public abstract class AbstractAnnotationConfigDispatcherServletInitializer
		extends AbstractDispatcherServletInitializer {
@Override
	@Nullable
	protected WebApplicationContext createRootApplicationContext() {
		// 获取父容器的配置类
		Class<?>[] configClasses = getRootConfigClasses();
		if (!ObjectUtils.isEmpty(configClasses)) {
			// 创建父容器
			AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
			// 注册配置类
			context.register(configClasses);
			return context;
		}
		else {
			return null;
		}
	}
}

3.SpringMvc容器

在AbstractDispatcherServletInitializer#registerDispatcherServlet方法中,主要做了4件事情

  1. 创建SpringMvc容器
  2. 创建DispatcherServlet
  3. 将DispatcherServlet 添加到Servlet容器中
  4. 给Servlet注册过滤器
	protected void registerDispatcherServlet(ServletContext servletContext) {
		String servletName = getServletName();
		Assert.hasLength(servletName, "getServletName() must not return null or empty");

		// 创建SpringMvc容器
		WebApplicationContext servletAppContext = createServletApplicationContext();
		Assert.notNull(servletAppContext, "createServletApplicationContext() must not return null");

		// 创建DispatcherServlet
		FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
		Assert.notNull(dispatcherServlet, "createDispatcherServlet(WebApplicationContext) must not return null");
		dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());

		// 将DispatcherServlet 添加到Servlet容器中
		ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
		if (registration == null) {
			throw new IllegalStateException("Failed to register servlet with name '" + servletName + "'. " +
					"Check if there is another servlet registered under the same name.");
		}

		// 启动立马加载
		registration.setLoadOnStartup(1);
		// 映射
		registration.addMapping(getServletMappings());
		registration.setAsyncSupported(isAsyncSupported());

		// 获取过滤器
		Filter[] filters = getServletFilters();
		if (!ObjectUtils.isEmpty(filters)) {
			for (Filter filter : filters) {
				// 给Servlet注册过滤器
				registerServletFilter(servletContext, filter);
			}
		}

		// 自定义扩展Servlet容器
		customizeRegistration(registration);
	}

3.1 创建SpringMvc容器

createServletApplicationContext方法仅仅是创建SpringMvc容器,并没有刷新启动该容器,启动过程后面再介绍,方法的实现在AbstractAnnotationConfigDispatcherServletInitializer

	protected WebApplicationContext createServletApplicationContext() {
		AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
		// 获取Sevlet配置类,这个配置类实现WebMvcConfigurer接口,主要配置视图解析器,拦截器等
		Class<?>[] configClasses = getServletConfigClasses();
		if (!ObjectUtils.isEmpty(configClasses)) {
			context.register(configClasses);
		}
		return context;
	}

3.2 创建DispatcherServlet

createDispatcherServlet这个方法很简单,里面就是new了一个DispatcherServlet对象

3.3 将DispatcherServlet 添加到Servlet容器中

将DispatcherServlet 添加到Servlet容器中,后续由它处理各种请求,getServletMappings是一个抽象方法,可以配置它处理的映射路径

3.4 给Servlet容器设置过滤器

设置过滤器时,可以重写getServletFilters方法

以上完成了容器的创建,接下来是启动容器


4.初始化DispatcherServlet

tomcat会自动调用DispatcherServlet#init方法进行初始化操作,具体的实现在HttpServletBean#init方法中,里面又调用initServletBean方法,实现在FrameworkServlet类中,重点关注FrameworkServlet#initWebApplicationContext方法,它的类关系图如下:
在这里插入图片描述
FrameworkServlet#initWebApplicationContext方法,里面重点关注configureAndRefreshWebApplicationContext方法

	protected WebApplicationContext initWebApplicationContext() {
		// 获取父容器
		WebApplicationContext rootContext =
				WebApplicationContextUtils.getWebApplicationContext(getServletContext());
		WebApplicationContext wac = null;

		// 此时的SprinMvc容器已经创建,所以不为null
		if (this.webApplicationContext != null) {
			// A context instance was injected at construction time -> use it
			wac = this.webApplicationContext;
			if (wac instanceof ConfigurableWebApplicationContext) {
				ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac;
				// 容器未启动
				if (!cwac.isActive()) {
					// The context has not yet been refreshed -> provide services such as
					// setting the parent context, setting the application context id, etc
					if (cwac.getParent() == null) {
						// The context instance was injected without an explicit parent -> set
						// the root application context (if any; may be null) as the parent
						cwac.setParent(rootContext);
					}
					// 配置且刷新启动web容器
					configureAndRefreshWebApplicationContext(cwac);
				}
			}
		}
		// 忽略其他代码
		return wac;
	}

4.1 配置且刷新启动SprinMvc容器

configureAndRefreshWebApplicationContext方法以下事情

  1. 对SprinMvc容器进行配置
  2. 刷新启动容器
	protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {
		
		// 设置Serlvet上下文
		wac.setServletContext(getServletContext());
		// 设置Servlet配置
		wac.setServletConfig(getServletConfig());
		wac.setNamespace(getNamespace());
		// web容器添加ContextRefreshListener监听器,监听ContextRefreshedEvent事件,执行DispatcherSevlet#onRefresh方法
		wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

		// 对web容器的扩展,留给子类扩展
		postProcessWebApplicationContext(wac);
		// 应用初始化器,也是对容器的一个扩展
		applyInitializers(wac);
		// 刷新启动容器
		wac.refresh();
	}

上面注册了一个SourceFilteringListener监听器,这个接口是一个适配器,最后委托给ContextRefreshListener#onApplicationEvent方法处理监听事件,下面再讲

refresh()方法刷新容器,重点关注的是它发布了ContextRefreshedEvent事件,ContextRefreshListener正是监听处理该事件

		// Publish the final event.
		// 发布上下文Refreshed完成事件
		publishEvent(new ContextRefreshedEvent(this));

4.2 初始化DispatcherServlet的默认配置,如视图解析器等

这个的初始化操作就是在上面提到的监听ContextRefreshedEvent事件完成,具体实现在ContextRefreshListener#onApplicationEvent方法,如下

// ContextRefreshListener是FrameworkServlet内部类
private class ContextRefreshListener implements ApplicationListener<ContextRefreshedEvent> {

		@Override
		public void onApplicationEvent(ContextRefreshedEvent event) {
			FrameworkServlet.this.onApplicationEvent(event);
		}
	}
public void onApplicationEvent(ContextRefreshedEvent event) {
		this.refreshEventReceived = true;
		synchronized (this.onRefreshMonitor) {
			// 实际调用DispatcherServlet#onRefresh
			onRefresh(event.getApplicationContext());
		}
	}

DispatcherServlet#onRefresh

	
	protected void onRefresh(ApplicationContext context) {
		initStrategies(context);
	}

	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);
		initLocaleResolver(context);
		initThemeResolver(context);
		initHandlerMappings(context);
		initHandlerAdapters(context);
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}

以上这些处理器,解析器都是通过@EnableMvcConfig 注入到容器中的,这里只是从容器中获取并赋值给DispatcherServlet相关属性

@EnableMvcConfig开启springmvc注解方式配置,它会委托DelegatingWebMvcConfiguration扫描到容器中所有实现WebMvcConfigurer接口的bean,而我们注入各种处理器和解析器也可以通过实现WebMvcConfigurer接口注入相关的处理器和解析器

在初始化的过程中先是从容器中获取,如果容器中没有,有些配置有兜底方案,比如initHandlerMappings方法

private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;
		// 默认为true
		if (this.detectAllHandlerMappings) {
			// 在容器中找HandlerMapping类型的bean
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			
		}
		// 或略其他代码

		// 容器中没有,兜底方案
		if (this.handlerMappings == null) {
			// 加载DispatcherServlet.properties 文件中定义的相关实现类
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

getDefaultStrategies 方法在类路径相同包名资源下的DispatcherServlet.properties文件中找默认的实现类,key为接口的全类名,value为相关实现类数组,如spring-webmvc中定义

在这里插入图片描述

以上就是SpringMvc注解启动的大体流程,如有不对的地方,欢迎留言指正

从零到千兆:KSZ9031 PHY芯片在Zynq PS端的驱动移植心路历程 本文详细记录了在Xilinx Zynq-7000平台(基于XC7Z020芯片)上,为KSZ9031千兆以太网PHY芯片移植LwIP协议栈驱动的完整过程。从硬件连接配置、Vivado工程设置到LwIP库的深度修改与调试,分享了解决PHY识别、自协商及性能优化等关键问题的实战经验,助力开发者实现稳定的千兆网络连接。 阅读详情

相关推荐

MS建模mmt

一、流程:1.定义好每个原子力场类型:Edit Sets(分组) 2.加H(一般是仅与Al-O八面体中的Al相连的O原子)、给H分组 3.“make P1”、校核化学式(正确与否) 4.扩成超晶胞(Na-mmt:4*1*1,Ca-mmt:4*2*1,illite:2*1*1,由化学式而定) 5.置换阳离子: mmt:模型中每 32 个 Si 4+有 1 个被 Al 3+ 取...

weixin_30721899的博客 2174

SpringMVC 启动流程源码分析

内容来自【自学星球】欢迎大家来了解我的星球,和星主(也就是我)一起学习 Java ,深入 Java 体系中的所有技术。我给自己定的时间是一年,无论结果如何,必定能给星球中的各位带来点东西。

技术分享、唠嗑水文、如有不周、还望海涵 662

各种逻辑漏洞

注册:短信轰炸验证码安全问题密码爆破邮箱轰炸用户任意注册、批量注册用户名枚举XSS(有框的地方就可以尝试插XSS)登录:短信轰炸、验证码安全问题、密码爆破、邮箱轰炸SQL注入撞库抓包把password字段修改为空值发送认证凭证替换、比如返回的数据包中包含账号,修改账号就能登录到其他账号Cookie仿冒修改返回包的相关数据,可能会登陆到其他的用户找回密码:短信邮箱轰炸、短信邮箱劫持重置任意用户账户密码、验证码手机用户未统一验证直接跳过验证步骤。

shirlly_的博客 2093

springmvc源码-注解启动

servlet 介绍 Servlet是sun公司提供的一门用于开发动态web资源的技术。   Sun公司在其API中提供了一个servlet接口,用户若想用发一个动态web资源(即开发一个Java程序向浏览器输出数据),需要完成以下2个步骤:   1、编写一个Java类,实现servlet接口。   2、把开发好的Java类部署到web服务器中。   按照一种约定俗成的称呼习惯,通常我们也把实现了servlet接口的java程序,称之为Servlet Servlet 和 SpringMVC的关系 Sprin

weixin_44044929的博客 936

一步一步教你写股票走势图——K线图一(概述)

股票分时图部分已经开发完毕,受到了广大开发者的好评!界面、功能都挺完美,解决了好一些MP开发者的问题,博主甚是欣悦,更有动力去开源K线图。这里说一下,如果有问题直接留言或者发邮件,github上个人信息有邮件,我看到基本都会回复,博主不加qq的,体谅O(∩_∩)O。分析好了,废话不多说,我们分析下K线图吧,首先我们看下自选股K线图的效果吧效果还是很赞的,经过分时图的研究后,博主越来越确信自选股用的应

体验Android编程之美 3万+

传感器模块的电路艺术:从引脚定义到系统集成的设计哲学

本文深入探讨传感器模块的电路设计艺术,从引脚定义到系统集成的完整设计哲学。重点解析电源管理、信号处理及I2C通信协议等核心电路原理,分享多模块协同中的电源架构、信号完整性和接地策略,为硬件工程师提供实用的系统级设计思维与实战案例。

o1p2q3r的博客 223

注解配置SpringMVC和MVC的执行流程

注解配置SpringMVC和MVC的执行流程

m0_62609939的博客 1014

NeRF-Pytorch(训练自己的数据集过程全记录+环境配置+COLMAP+问题解决)

写于2025/1/26,在用NeRF训练自己的数据集过程中该踩的坑都踩过了,发现网上并没有详细完整写这些问题解决过程的帖子,遂自己进行一个全记录和复盘。 整篇文章包括:NeRF训练环境配置;COLMAP三维重建过程(直接给出代码,规避一些bug);在训练时候出现的问题。 本篇文章仅针对llff格式数据集。

m0_62577716的博客 1774

springMVC全注解启动和容器的初始化

前言 在学习springMVC注解启动启动之前,我们先了解下ServletContainerInitializer。 在web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer的onStartup(Set<Class<?>> var1, ServletC...

clyu的博客 4549

1、电路分析知识全解析:从基础到实践应用

本博客全面解析电路分析知识体系,涵盖从基础的电压、电流、电阻概念到复杂的交流电路、瞬态分析和高级应用如滤波器与变压器等内容。适合电子技术专业学生和技术爱好者学习,提供详细的知识结构、学习路径、实践示例以及丰富的学习资源,包括计算机模拟工具Multisim和PSpice的使用指导。通过理论与实践结合,帮助学习者掌握电路分析的核心技能,为电子工程和电力系统等相关领域打下坚实基础。

iii12的专栏 159

大数据与宠物:健康监测数据分析

随着全球宠物市场规模的快速增长(2023年全球宠物产业规模已达3500亿美元),宠物健康管理需求呈现指数级上升。传统宠物医疗依赖定期体检和症状观察,存在滞后性和主观性缺陷。本文聚焦如何通过物联网(IoT)设备采集宠物生理数据(体温、心率、活动量等),利用大数据分析技术构建实时健康监测系统,实现宠物健康状态的动态评估、异常预警和疾病预测。研究范围涵盖数据采集技术、数据预处理方法、机器学习模型构建及实际应用场景落地。背景介绍:明确研究目的、目标读者及核心术语核心概念与联系。

2502_91592937的博客 1068

SpringMVC源码探究——SpringMVC的启动及容器初始化(注解方式)

servlet规范规定,在servlet启动时,要通过ServletContainerInitializer处理所有@HandlesTypes中标注的类,而ServletContainerInitializer是一个接口。 而ServletContainerInitializer的实现类是Tomcat通过SPI机制加载的。 1.SPI机制 根据以上的知识,我们可以找到SpirngMVC实现了ServletContainerInitializer的类:SpringServletContainerIniti

weixin_48680790的博客 578

第 1 章 Prometheus 监控 | Prometheus 入门

了解 Prometheus 监控系统,学会安装及了解页面功能。

甘蓝的专栏 486

基于注解的 springmvc整合

原理: 1、web容器在启动的时候,会扫描每个jar包下的META-INF/services/javax.servlet.ServletContainerInitializer 2、加载这个文件指定的类SpringServletContainerInitializer 3、spring的应用一启动会加载感兴趣的WebApplicationInitializer接口下的...

u014450465的博客 149

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

springMvc02 基于注解版本的

1.springMvc基于注解版(maven项目) 1.1 先引入springMvc和Servlet3.0的依赖包 &amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.a.

qq_14931985的博客 248

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

【Spring】源码解析SpringMVC容器的启动过程

这里是重点:这个方法中干了4件事情创建父容器,只是实例化了,并未启动创建了监听器ContextLoaderListener,这是一个ServletContextListener类型的监听器,稍后会在这个监听器中启动父容器创建springmvc容器,只是实例化了,并未启动,启动的事情会在DispatcherServlet#init中做,稍后会说Servlet容器中注册DispatcherServlet下面,咱们来详细看这几个步骤,把这几个步骤作为阶段来解读。

九师兄 207

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

Spring Boot2.0之注解方式启动Springmvc

Spring Boot2.0之注解方式启动Springmvc 回顾下springmvc原理图: DispatcherServlet是Spring MVC的核心,每当应用接受一个HTTP请求,由DispatcherServlet负责将请求分发给应用的其他组件。 在旧版本中,DispatcherServlet之类的servlet一般在web.xml文件中配置,该文件一般会打包进最...

art_code的博客 355

Spring MVC初始化过程-源码解析

背景 在SpringMVC项目配置中,我使用了xml的方式来启动SptingMVC对声明式注解的支持,其中使用如下标签进行启动 <!--支持注解方式声明@Controller--> <mvc:annotation-driven /> 因为解析配置文件过程中,需要对其中的标签进行解析,而这里使用的是自定义标签,则需要有对应相关的处理器和解析器 标签解析过程 <mvc:annotation-driven /> 解析自定义标签 MvcNamespaceHandler 因

是狮不是猿 285

SpringMVC纯注解配置+原理详解【请求流程预备点】

SpringMVC系列这里都基于纯注解的方式。而要实现纯注解,就是要替代原本的web.xml和springmvc.xml两个配置文件的内容。 一、替代web.xml 1.1 spring配置 不扫描Controller类 @ComponentScan(value = "com.wml",excludeFilters = { @ComponentScan.Filter(type = ...

一颗小陨石的博客 1115

SpringMVC源码分析_1 SpringMVC容器启动和加载原理

SpringMVC源码分析_1 SpringMVC启动和加载原理 1 SpringMVC容器启动和加载原理 ...

田宝宝的博客 5378

【SpringMVC】SPI、父子容器、xml与注解式配置解读

一、回顾Servlet @WebServlet("/hello") public class HelloServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //super.doGet(req, resp); System.out.println(T

努力充实,远方可期 692

互联网架构-SpringMVC源码深度解析-027:Servlet与SpringMVC关系

027:Servlet与SpringMVC关系1 SpringMVC深度源码分析课程介绍2 基于ide构建ServletMaven工程3 如何证明Servlet线程是否安全4 ServletContainerInitializer用法5 基于注解方式构建SpringMVC框架6 使用注解形式启动SpringMVC项目7 SpringServletContainerInitializer源码分析 1 SpringMVC深度源码分析课程介绍 课题内容: 1.Servlet与SpringMVC之间的关系 2.Se

枫火的博客 1047

【小家Spring】Spring容器(含父子容器)的启动过程源码级别分析(含web.xml启动以及全注解驱动,和ContextLoader源码分析)

前言 最近在编写Spring相关博文的时候,发现有不少小伙伴对口头上经常说到的Spring容器、父子容器等等概念,既熟悉,又默认。大体知道它是干啥的,但是却有不太能知道所以然 因此本文自己也本着一个学习的态度,主要介绍Spring容器(父子容器)的启动过程。由于我们有web.xml配置文件的方式以及这里讲到过的全注解驱动的方式,因此本文都分开来讲述。 备注:本文讲述不包括Spring Boot中...

架构师:通透,才能写出好代码! 6632

SpringMVC源码(三):Spring整合SpringMVC以及父子容器启动流程分析

Spring整合SpringMVC Spring整合SpringMVC的方式是父子容器形式 父容器Spring管理Service、Dao层的Bean 子容器SpringMVC管理Controller的Bean 子容器可以访问父容器的Bean,父容器无法访问子容器的Bean 而SpringBoot是SpringMVC零Xml配置基础上出现的,那SpringMVC的零Xml配置是如何实现的? 就是把web.xml中负责父容器ContextLoaderListener和子容器DispatcherServlet通过

Men-DD 1142

SpringMVC源码解析(1)-启动过程

SpringMVC源码解析系列1-启动过程 xml方式 springmvc标签解析 java方式 xml方式 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com...

weixin_33949359的博客 154

手写springmvc

springMVC的理解 springmvc框架在MVC模式中充当-C的作用,也就是控制层,springmvc是spring公司的一个框架,在整合spring框架的时候也依赖于spring的IOC容器,对象的生命周期交于spring管理。springMVC是对Servlet的封装,可以让我们达到快速开发的效果。 springMVC的启动过程 为了使过程更清晰明了,我们不加入springmvc的依赖...

qq_38021775的博客 449
下一篇: SpringBoot启动流程、源码一步一步分析
wvmiboy
博客等级 码龄10年 14粉丝 5原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值