Spring进阶(spring进阶培训)

  本篇文章为你整理了Spring进阶(spring进阶培训)的详细内容,包含有spring进阶推荐书籍 spring进阶培训 spring入门经典 spring integration入门 Spring进阶,希望能帮助你了解 Spring进阶。

   Java 全栈知识体系 ❁导航 ♥面试 ✿导读 JavaJavaJava 面向对象和基础 Java 面向对象基础 Java 基础知识体系 Java进阶 - 集合框架 Java 集合框架详解 Java进阶 - 并发框架 Java 并发知识体系 Java 并发理论基础 Java 并发线程基础 J.U.C 知识体系与详解 Java进阶 - IO框架 Java IO/NIO/AIO详解 Java进阶 - 新版本特性 Java 8 特性详解 Java 8 以上版本特性体系 Java 8 升Java 11特性必读 Java 11 升Java 17特性必读 Java进阶 - JVM相关 Java 类加载机制 Java 字节码和增强技术 JVM 内存结构详解 JVM 垃圾回收机制 Java 调试排错相关 算法算法算法基础和思想 数据结构基础 常见排序算法 算法思想 一些领域算法 安全算法 字符串匹配算法 分布式系统算法 海量数据处理 负载均衡算法 推荐算法 数据挖掘算法 ID生成算法 其它算法相关 头脑风暴 数据库数据库数据库基础和原理 数据库原理 SQL语言 SQL 数据库 MySQL 详解 NoSQL 数据库 Redis 详解 MongoDB 详解 ElasticSearch 详解 开发开发开发 - 常用开发基础 常用类库详解 正则表达式详解 CRON表达式详解 网络协议和工具详解 安全相关详解 开发 - 质量保障 单元测试详解 统一风格详解 质量管理详解 开发 - 代码重构 代码重构相关 SpringSpringSpring Framework(v5.3) Spring框架知识体系 Spring框架组成 控制反转(IOC) 面向切面编程(AOP) SpringMVC SpringBoot系列(v2.5) SpringBoot知识体系 SpringBoot入门 SpringBoot接口设计和实现 SpringBoot集成MySQL SpringBoot集成ShardingJDBC SpringBoot集成Redis SpringBoot集成Postgre SpringBoot集成ElasticSearch SpringBoot集成Socket SpringBoot定时任务 SpringBoot后端视图 SpringBoot监控 SpringBoot进阶 框架中间件框架中间件Web 容器 Tomcat 源码详解 ORM 框架 MyBatis 源码详解 分表分库框架 ShardingSphere 详解 架构架构架构基础和技术点 架构知识体系 从角色视角看架构 从分层视角看架构 从演化视角看架构 从模式视角看架构 高并发之缓存 高并发之限流 高并发之降级和熔断 高可用之负载均衡 高可用之容灾备份 分布式系统 分布式理论和一致性算法 全局唯一ID实现方案 分布式锁及实现方案 分布式事务及实现方案 分布式任务及实现方案 分布式会话及实现方案 微服务系统 微服务系统和设计 系统设计之商业业务平台 秒杀抽奖相关设计 电商交易相关设计 仓储物流相关设计 拉新投放相关设计 其它综合相关设计 系统设计之数据仓库平台 数据库架构相关设计 数据同步相关设计 数据仓库相关设计 数据治理相关设计 工具部署工具部署 开发工具 Git详解 Linux Docker 项目 方法论方法论开发理论 开发原则(SOLID) 分布式理论(CAP) 分布式理论(BASE) 事务理论(ACID) 微服务理论(康威定律) 开源协议 常见开源协议详解 知识共享许可协议 国产开源木兰协议 代码规范 阿里巴巴 Java开发手册 Google Java 编程风格指南 Twitter Java代码规范 开发流程 软件生命周期与传统模型 结合测试演化的过程模型 敏捷开发项目管理理论 敏捷之极限编程(XP) 敏捷之Scrum Kanban 敏捷实践之测试驱动开发 设计模式 设计模式详解 系统认证 CMMI 认证 等级保护认证 ISO27001认证 产品团队产品团队技术之外 技术之外应该思考什么 个人相关 个人成长和认知 产品相关 产品设计和思考 团队相关 管对管理和成长 其它相关 其它软实力等 关于 ❁导航 ♥面试 ✿导读 JavaJavaJava 面向对象和基础 Java 面向对象基础 Java 基础知识体系 Java进阶 - 集合框架 Java 集合框架详解 Java进阶 - 并发框架 Java 并发知识体系 Java 并发理论基础 Java 并发线程基础 J.U.C 知识体系与详解 Java进阶 - IO框架 Java IO/NIO/AIO详解 Java进阶 - 新版本特性 Java 8 特性详解 Java 8 以上版本特性体系 Java 8 升Java 11特性必读 Java 11 升Java 17特性必读 Java进阶 - JVM相关 Java 类加载机制 Java 字节码和增强技术 JVM 内存结构详解 JVM 垃圾回收机制 Java 调试排错相关 算法算法算法基础和思想 数据结构基础 常见排序算法 算法思想 一些领域算法 安全算法 字符串匹配算法 分布式系统算法 海量数据处理 负载均衡算法 推荐算法 数据挖掘算法 ID生成算法 其它算法相关 头脑风暴 数据库数据库数据库基础和原理 数据库原理 SQL语言 SQL 数据库 MySQL 详解 NoSQL 数据库 Redis 详解 MongoDB 详解 ElasticSearch 详解 开发开发开发 - 常用开发基础 常用类库详解 正则表达式详解 CRON表达式详解 网络协议和工具详解 安全相关详解 开发 - 质量保障 单元测试详解 统一风格详解 质量管理详解 开发 - 代码重构 代码重构相关 SpringSpringSpring Framework(v5.3) Spring框架知识体系 Spring框架组成 控制反转(IOC) 面向切面编程(AOP) SpringMVC SpringBoot系列(v2.5) SpringBoot知识体系 SpringBoot入门 SpringBoot接口设计和实现 SpringBoot集成MySQL SpringBoot集成ShardingJDBC SpringBoot集成Redis SpringBoot集成Postgre SpringBoot集成ElasticSearch SpringBoot集成Socket SpringBoot定时任务 SpringBoot后端视图 SpringBoot监控 SpringBoot进阶 框架中间件框架中间件Web 容器 Tomcat 源码详解 ORM 框架 MyBatis 源码详解 分表分库框架 ShardingSphere 详解 架构架构架构基础和技术点 架构知识体系 从角色视角看架构 从分层视角看架构 从演化视角看架构 从模式视角看架构 高并发之缓存 高并发之限流 高并发之降级和熔断 高可用之负载均衡 高可用之容灾备份 分布式系统 分布式理论和一致性算法 全局唯一ID实现方案 分布式锁及实现方案 分布式事务及实现方案 分布式任务及实现方案 分布式会话及实现方案 微服务系统 微服务系统和设计 系统设计之商业业务平台 秒杀抽奖相关设计 电商交易相关设计 仓储物流相关设计 拉新投放相关设计 其它综合相关设计 系统设计之数据仓库平台 数据库架构相关设计 数据同步相关设计 数据仓库相关设计 数据治理相关设计 工具部署工具部署 开发工具 Git详解 Linux Docker 项目 方法论方法论开发理论 开发原则(SOLID) 分布式理论(CAP) 分布式理论(BASE) 事务理论(ACID) 微服务理论(康威定律) 开源协议 常见开源协议详解 知识共享许可协议 国产开源木兰协议 代码规范 阿里巴巴 Java开发手册 Google Java 编程风格指南 Twitter Java代码规范 开发流程 软件生命周期与传统模型 结合测试演化的过程模型 敏捷开发项目管理理论 敏捷之极限编程(XP) 敏捷之Scrum Kanban 敏捷实践之测试驱动开发 设计模式 设计模式详解 系统认证 CMMI 认证 等级保护认证 ISO27001认证 产品团队产品团队技术之外 技术之外应该思考什么 个人相关 个人成长和认知 产品相关 产品设计和思考 团队相关 管对管理和成长 其它相关 其它软实力等 关于 Spring Framework 5基础

   ♥Spring框架知识体系详解♥ Spring基础 - Spring和Spring框架组成 Spring基础 - Spring简单例子引入Spring要点 Spring基础 - Spring核心之控制反转(IOC) Spring基础 - Spring核心之面向切面编程(AOP) Spring基础 - SpringMVC请求流程和案例 Spring进阶- Spring IOC实现原理详解之IOC体系结构设计 Spring进阶- Spring IOC实现原理详解之IOC初始化流程 Spring进阶- Spring IOC实现原理详解之Bean实例化(生命周期,循环依赖等) Spring进阶 - Spring AOP实现原理详解之AOP切面的实现 Spring进阶 - Spring AOP实现原理详解之AOP代理的创建 Spring进阶 - Spring AOP实现原理详解之Cglib代理实现 Spring进阶 - Spring AOP实现原理详解之JDK代理实现 Spring进阶 - SpringMVC实现原理之DispatcherServlet的初始化过程 Spring进阶 - SpringMVC实现原理之DispatcherServlet处理请求的过程 SpringBoot 2.5.x系列

   ♥SpringBoot 知识体系详解♥ ▶SpringBoot入门 - SpringBoot简介 SpringBoot入门 - SpringBoot HelloWorld SpringBoot入门 - 对Hello world进行MVC分层 SpringBoot入门 - 添加内存数据库H2 SpringBoot入门 - 定制自己的Banner SpringBoot入门 - 添加Logback日志 SpringBoot入门 - 配置热部署devtools工具 SpringBoot入门 - 开发中还有哪些常用注解 ▶SpringBoot接口 - 如何统一接口封装 SpringBoot接口 - 如何对参数进行校验 SpringBoot接口 - 如何参数校验国际化 SpringBoot接口 - 如何统一异常处理 SpringBoot接口 - 如何提供多个版本接口 SpringBoot接口 - 如何生成接口文档之Swagger技术栈 SpringBoot接口 - 如何生成接口文档之集成Smart-Doc SpringBoot接口 - 如何访问外部接口 SpringBoot接口 - 如何保证接口幂等 SpringBoot接口 - 如何对接口进行签名 SpringBoot接口 - 如何实现接口限流之单实例 SpringBoot接口 - 如何实现接口限流之分布式 ▶SpringBoot集成MySQL - 基于JPA的封装 SpringBoot集成MySQL - MyBatis XML方式 SpringBoot集成MySQL - MyBatis 注解方式 SpringBoot集成MySQL - MyBatis PageHelper分页 SpringBoot集成MySQL - MyBatis 多个数据源 SpringBoot集成MySQL - MyBatis-Plus方式 SpringBoot集成MySQL - MyBatis-Plus代码自动生成 SpringBoot集成MySQL - MyBatis-Plus基于字段隔离的多租户 ▶SpringBoot集成ShardingJDBC - Sharding-JDBC简介和基于MyBatis的单库分表 SpringBoot集成ShardingJDBC - 基于JPA的单库分表 SpringBoot集成ShardingJDBC - 基于JPA的读写分离 SpringBoot集成ShardingJDBC - 基于JPA的DB隔离多租户方案 ▶SpringBoot集成连接池 - 数据库连接池和默认连接池HikariCP SpringBoot集成连接池 - 集成数据库Druid连接池 ▶SpringBoot数据库管理 - 用Liquibase对数据库管理和迁移 SpringBoot数据库管理 - 用flyway对数据库管理和迁移 ▶SpringBoot集成PostgreSQL - 基于JPA封装基础数据操作 SpringBoot集成PostgreSQL - 基于MyBatis-Plus方式 SpringBoot集成PostgreSQL - NoSQL特性JSONB的封装 ▶SpringBoot集成Redis - 基于RedisTemplate+Jedis的数据操作 SpringBoot集成Redis - 基于RedisTemplate+Lettuce数据操作 SpringBoot集成Redis - 基于RedisTemplate+Lettuce数据类封装 SpringBoot集成Redis - Redis分布式锁的实现之Jedis(setNXPX+Lua) ▶SpringBoot集成MongoDB - 基于MongoTemplate的数据操作 ▶SpringBoot集成ElasticSearch - 基于ElasticSearchTemplate的数据操作 ▶SpringBoot集成Socket - 基础的Websocket实现 SpringBoot集成Socket - 用Netty实现socket ▶SpringBoot定时任务 - Timer实现方式 SpringBoot定时任务 - ScheduleExecutorService实现方式 SpringBoot定时任务 - Netty HashedWheelTimer方式 SpringBoot定时任务 - Spring Schedule实现方式 SpringBoot定时任务 - 基础quartz实现方式 SpringBoot定时任务 - 分布式quartz cluster方式 SpringBoot定时任务 - 分布式elastic-job方式 SpringBoot定时任务 - 分布式xxl-job方式 ▶SpringBoot集成文件 - 基础的文件上传和下载 SpringBoot集成文件 - 大文件的上传(异步,分片,断点续传和秒传) SpringBoot集成文件 - 集成POI之Excel导入导出 SpringBoot集成文件 - 集成EasyExcel之Excel导入导出 SpringBoot集成文件 - 集成EasyPOI之Excel导入导出 SpringBoot集成文件 - 集成POI之Word导出 SpringBoot集成文件 - 集成POI-tl之基于模板的Word导出 SpringBoot集成文件 - 集成itextpdf之导出PDF ▶SpringBoot后端视图 - 基于Thymeleaf视图解析 ▶SpringBoot集成JavaFX2 - JavaFX 2.0应用 ▶SpringBoot应用部署 - 打包成jar部署 SpringBoot应用部署 - 使用第三方JAR包 SpringBoot应用部署 - 打包成war部署 SpringBoot应用部署 - 替换tomcat为Jetty容器 SpringBoot应用部署 - 替换tomcat为Undertow容器 SpringBoot应用部署 - 在linux环境将jar制作成service SpringBoot应用部署 - docker镜像打包,运行和管理 SpringBoot应用部署 - 使用Docker Compose对容器编排管理 ▶SpringBoot监控 - 集成actuator监控工具 SpringBoot监控 - 集成springboot admin监控工具 ▶SpringBoot进阶 - 实现自动装配原理 SpringBoot进阶 - 自定义starter SpringBoot进阶 - 嵌入web容器Tomcat原理 SpringBoot进阶 - 健康检查Actuator原理 # Spring进阶 - SpringMVC实现原理之DispatcherServlet的初始化过程前文我们有了IOC的源码基础以及SpringMVC的基础,我们便可以进一步深入理解SpringMVC主要实现原理,包含DispatcherServlet的初始化过程和DispatcherServlet处理请求的过程的源码解析。本文是第一篇:DispatcherServlet的初始化过程的源码解析。@pdai

  Spring进阶 - SpringMVC实现原理之DispatcherServlet的初始化过程DispatcherServlet和ApplicationContext有何关系?DispatcherServlet是如何初始化的?initinitWebApplicationContextrefreshinitHanlderxxx# DispatcherServlet和ApplicationContext有何关系?DispatcherServlet 作为一个 Servlet,需要根据 Servlet 规范使用 Java 配置或 web.xml 声明和映射。反过来,DispatcherServlet 使用 Spring 配置来发现请求映射、视图解析、异常处理等等所需的委托组件。那它和ApplicationContext有和关系呢?如下内容可以参考官网-SpringMVC文档在新窗口打开

  DispatcherServlet 需要 WebApplicationContext(继承自 ApplicationContext) 来配置。WebApplicationContext 可以链接到ServletContext 和 Servlet。因为绑定了 ServletContext,这样应用程序就可以在需要的时候使用 RequestContextUtils 的静态方法访问 WebApplicationContext。

  大多数应用程序只有一个WebApplicationContext,除此之外也可以一个Root WebApplicationContext 被多个 Servlet实例,然后各自拥有自己的Servlet WebApplicationContext 配置。

  Root WebApplicationContext 包含需要共享给多个 Servlet 实例的数据源和业务服务基础 Bean。这些 Bean 可以在 Servlet 特定的范围被继承或覆盖。

  (PS:官网上的这张图可以可以帮助你构建DispatcherServlet和ApplicationContext在设计上的认知,这一点对于理解DispatcherServlet的设计和初始化过程非常重要)

  # DispatcherServlet是如何初始化的?DispatcherServlet首先是Sevlet,Servlet有自己的生命周期的方法(init,destory等),那么我们在看DispatcherServlet初始化时首先需要看源码中DispatcherServlet的类结构设计。

  首先我们看DispatcherServlet的类结构关系,在这个类依赖结构中找到init的方法

  很容易找到init()的方法位于HttpServletBean中,然后跑Spring基础 - SpringMVC请求流程和案例中的代码,在init方法中打断点。

  # initinit()方法如下, 主要读取web.xml中servlet参数配置,并将交给子类方法initServletBean()继续初始化

  

/**

 

   * Map config parameters onto bean properties of this servlet, and

   * invoke subclass initialization.

   * @throws ServletException if bean properties are invalid (or required

   * properties are missing), or if subclass initialization fails.

  @Override

  public final void init() throws ServletException {

   // 读取web.xml中的servlet配置

   PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);

   if (!pvs.isEmpty()) {

   try {

   // 转换成BeanWrapper,为了方便使用Spring的属性注入功能

   BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);

   // 注入Resource类型需要依赖于ResourceEditor解析,所以注册Resource类关联到ResourceEditor解析器

   ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());

   bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));

   // 更多的初始化可以让子类去拓展

   initBeanWrapper(bw);

   // 让spring注入namespace,contextConfigLocation等属性

   bw.setPropertyValues(pvs, true);

   catch (BeansException ex) {

   if (logger.isErrorEnabled()) {

   logger.error( Failed to set bean properties on servlet + getServletName() + , ex);

   throw ex;

   // 让子类去拓展

   initServletBean();

  

读取配置可以从下图看出,正是初始化了我们web.xml中配置

 

  再看下initServletBean()方法,位于FrameworkServlet类中

  

/**

 

   * Overridden method of {@link HttpServletBean}, invoked after any bean properties

   * have been set. Creates this servlet s WebApplicationContext.

  @Override

  protected final void initServletBean() throws ServletException {

   getServletContext().log( Initializing Spring + getClass().getSimpleName() + + getServletName() + );

   if (logger.isInfoEnabled()) {

   logger.info( Initializing Servlet + getServletName() + );

   long startTime = System.currentTimeMillis();

   try {

   // 最重要的是这个方法

   this.webApplicationContext = initWebApplicationContext();

   // 可以让子类进一步拓展

   initFrameworkServlet();

   catch (ServletException RuntimeException ex) {

   logger.error( Context initialization failed , ex);

   throw ex;

   if (logger.isDebugEnabled()) {

   String value = this.enableLoggingRequestDetails ?

   shown which may lead to unsafe logging of potentially sensitive data :

   masked to prevent unsafe logging of potentially sensitive data ;

   logger.debug( enableLoggingRequestDetails= + this.enableLoggingRequestDetails +

   : request parameters and headers will be + value);

   if (logger.isInfoEnabled()) {

   logger.info( Completed initialization in + (System.currentTimeMillis() - startTime) + ms );

  

# initWebApplicationContextinitWebApplicationContext用来初始化和刷新WebApplicationContext。

 

  initWebApplicationContext() 方法如下

  

/**

 

   * Initialize and publish the WebApplicationContext for this servlet.

   * p Delegates to {@link #createWebApplicationContext} for actual creation

   * of the context. Can be overridden in subclasses.

   * @return the WebApplicationContext instance

   * @see #FrameworkServlet(WebApplicationContext)

   * @see #setContextClass

   * @see #setContextConfigLocation

  protected WebApplicationContext initWebApplicationContext() {

   WebApplicationContext rootContext =

   WebApplicationContextUtils.getWebApplicationContext(getServletContext());

   WebApplicationContext wac = 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);

   configureAndRefreshWebApplicationContext(cwac);

   // 没有在构造函数中初始化,则尝试通过contextAttribute初始化

   if (wac == null) {

   // No context instance was injected at construction time - see if one

   // has been registered in the servlet context. If one exists, it is assumed

   // that the parent context (if any) has already been set and that the

   // user has performed any initialization such as setting the context id

   wac = findWebApplicationContext();

   // 还没有的话,只能重新创建了

   if (wac == null) {

   // No context instance is defined for this servlet - create a local one

   wac = createWebApplicationContext(rootContext);

   if (!this.refreshEventReceived) {

   // Either the context is not a ConfigurableApplicationContext with refresh

   // support or the context injected at construction time had already been

   // refreshed - trigger initial onRefresh manually here.

   synchronized (this.onRefreshMonitor) {

   onRefresh(wac);

   if (this.publishContext) {

   // Publish the context as a servlet context attribute.

   String attrName = getServletContextAttributeName();

   getServletContext().setAttribute(attrName, wac);

   return wac;

  

webApplicationContext只会初始化一次,依次尝试构造函数初始化,没有则通过contextAttribute初始化,仍没有则创建新的

 

  创建的createWebApplicationContext方法如下

  

/**

 

   * Instantiate the WebApplicationContext for this servlet, either a default

   * {@link org.springframework.web.context.support.XmlWebApplicationContext}

   * or a {@link #setContextClass custom context class}, if set.

   * p This implementation expects custom contexts to implement the

   * {@link org.springframework.web.context.ConfigurableWebApplicationContext}

   * interface. Can be overridden in subclasses.

   * p Do not forget to register this servlet instance as application listener on the

   * created context (for triggering its {@link #onRefresh callback}, and to call

   * {@link org.springframework.context.ConfigurableApplicationContext#refresh()}

   * before returning the context instance.

   * @param parent the parent ApplicationContext to use, or {@code null} if none

   * @return the WebApplicationContext for this servlet

   * @see org.springframework.web.context.support.XmlWebApplicationContext

  protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) {

   Class ? contextClass = getContextClass();

   if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) {

   throw new ApplicationContextException(

   Fatal initialization error in servlet with name + getServletName() +

   : custom WebApplicationContext class [ + contextClass.getName() +

   ] is not of type ConfigurableWebApplicationContext );

   // 通过反射方式初始化

   ConfigurableWebApplicationContext wac =

   (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass);

   wac.setEnvironment(getEnvironment());

   wac.setParent(parent);

   String configLocation = getContextConfigLocation(); // 就是前面Demo中的springmvc.xml

   if (configLocation != null) {

   wac.setConfigLocation(configLocation);

   // 初始化Spring环境

   configureAndRefreshWebApplicationContext(wac);

   return wac;

  

configureAndRefreshWebApplicationContext方法初始化设置Spring环境

 

  

protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac) {

 

   // 设置context ID

   if (ObjectUtils.identityToString(wac).equals(wac.getId())) {

   // The application context id is still set to its original default value

   // - assign a more useful id based on available information

   if (this.contextId != null) {

   wac.setId(this.contextId);

   else {

   // Generate default id...

   wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX +

   ObjectUtils.getDisplayString(getServletContext().getContextPath()) + / + getServletName());

   // 设置servletContext, servletConfig, namespace, listener...

   wac.setServletContext(getServletContext());

   wac.setServletConfig(getServletConfig());

   wac.setNamespace(getNamespace());

   wac.addApplicationListener(new SourceFilteringListener(wac, new ContextRefreshListener()));

   // The wac environment s #initPropertySources will be called in any case when the context

   // is refreshed; do it eagerly here to ensure servlet property sources are in place for

   // use in any post-processing or initialization that occurs below prior to #refresh

   ConfigurableEnvironment env = wac.getEnvironment();

   if (env instanceof ConfigurableWebEnvironment) {

   ((ConfigurableWebEnvironment) env).initPropertySources(getServletContext(), getServletConfig());

   // 让子类去拓展

   postProcessWebApplicationContext(wac);

   applyInitializers(wac);

   // Spring环境初始化完了,就可以初始化DispatcherServlet处理流程中需要的组件了。

   wac.refresh();

  

# refresh有了webApplicationContext后,就开始刷新了(onRefresh()方法),这个方法是FrameworkServlet提供的模板方法,由子类DispatcherServlet来实现的。

 

  

/**

 

   * This implementation calls {@link #initStrategies}.

  @Override

  protected void onRefresh(ApplicationContext context) {

   initStrategies(context);

  

刷新主要是调用initStrategies(context)方法对DispatcherServlet中的组件进行初始化,这些组件就是在SpringMVC请求流程中包的主要组件。

 

  

/**

 

   * Initialize the strategy objects that this servlet uses.

   * p May be overridden in subclasses in order to initialize further strategy objects.

  protected void initStrategies(ApplicationContext context) {

   initMultipartResolver(context);

   initLocaleResolver(context);

   initThemeResolver(context);

   // 主要看如下三个方法

   initHandlerMappings(context);

   initHandlerAdapters(context);

   initHandlerExceptionResolvers(context);

   initRequestToViewNameTranslator(context);

   initViewResolvers(context);

   initFlashMapManager(context);

  

# initHanlderxxx我们主要看initHandlerXXX相关的方法,它们之间的关系可以看SpringMVC的请求流程:

 

  HandlerMapping是映射处理器HandlerAdpter是处理适配器,它用来找到你的Controller中的处理方法HandlerExceptionResolver是当遇到处理异常时的异常解析器initHandlerMapping方法如下,无非就是获取按照优先级排序后的HanlderMappings, 将来匹配时按照优先级最高的HanderMapping进行处理。

  initHandlerAdapters方法和initHandlerExceptionResolvers方法也是类似的,如果没有找。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: