接上文 Spring Developer Tools 源码分析:二、类路径监控,接下来看看前面提到的这些类是如何配置,如何启动的。

spring-boot-devtools 使用了 Spring Boot 的自动配置方式,我们先关注本地开发环境中自动重启的部分。

在 LocalDevToolsAutoConfiguration 主要包含了 LiveReload 和重启的配置,LiveReload 后续看情况再介绍,这里先看重启的配置。

3.1 LocalDevToolsAutoConfiguration 本地配置

在这个类上 @ConditionalOnInitializedRestarter 是一个该配置生效的条件,具体实现中会判断 Restarter 是否已经实例化,并且是否存在可被监控的类目录(除 jar 文件外的目录),如果已经实例化,并且有需要监控的目录才会启动。

通过 java -jar 方式启动的时候,由于不存在需要监控的目录,devtools 不会触发后续的配置,因此虽然启动了 Restarter,但是并不会监控目录,也不会自动重启。

当通过 IDE 启动项目时,默认情况下会满足这里的条件,LocalDevToolsAutoConfiguration 中的其他配置可以生效。

3.2 RestartConfiguration 重启配置

在 RestartConfiguration 上也有限制条件,只有当设置下面的参数时才不会生效


不设置或者设置为任何不是 false (忽略大小写)的值时,都会生效。

除了这个参数能控制外,还有一个可以直接控制 Restarter 是否生效的参数,后续会介绍。

下面逐个看 RestartConfiguration 中的各个配置。

3.2.1 FileSystemWatcherFactory 文件监控

配置代码如下:


FileSystemWatcherFactory 是一个函数式接口,这里直接返回了一个方法引用。将来调用该接口的方法时,就会执行下面的 newFileSystemWatcher 方法。

每次调用 fileSystemWatcherFactory() 方法时,返回的都是同一个 FileSystemWatcherFactory,但是调用工厂的 getFileSystemWatcher() 方法时返回都是新的 FileSystemWatcher。

通过这个方法可以看到创建 FileSystemWatcher 时,这里会判断是否配置了触发文件(只有修改指定文件才会重启),是否配置额外需要监控变化的位置。Java架构交流学习圈:874811168 面向1-3年经验 Java开发人员 帮助突破瓶颈 提升思维能力

3.2.2 ClassPathRestartStrategy 重启策略

代码如下:


该方法返回了 PatternClassPathRestartStrategy 实现类,判断是否重启时,忽略所有传入的位置,默认忽略的位置如下:


额外的排除项可以通过下面的参数设置:


3.2.3 ClassPathFileSystemWatcher 类路径监控

代码如下:


这里创建时,从 Restarter 获取了需要监控的类路径(后续会详细介绍),然后创建了一个 watcher,使用了前面创建的两个 bean。setStopWatcherOnRestart 的意思是当类路径发生变化并且需要重启时,是否停止类监控,这里设置了 true,也就是重启前会停止监控。

如果重启前会停止监控,我们可能需要担心如果配置改错了导致 Spring 无法启动该怎么办,devtools 也提供了相应的策略来解决这个问题,下一小节就会看到。

3.2.3 监听 ClassPathChangedEvent

代码如下:


当一个方法添加 @EventListener 时,Spring 会把该方法添加到事件监听中,当触发该事件时,这个方法就会被调用。在上一篇介绍了 ClassPathChangedEvent,其中包含了 restartRequired,这里会判断是否需要重启,当需要重启时,就会调用 Restarter 的实例进行重启。

在重启方法中还传入了 FileWatchingFailureHandler 并且使用了 fileSystemWatcherFactory。

FileWatchingFailureHandler 实现了 FailureHandler 接口,该接口用于在重启的启动过程中,如果出错了,要采取什么策略去进行下去,该接口方法返回的结果只有两种,Outcome.ABORT 中止或 Outcome.RETRY 重试。

FileWatchingFailureHandler 中会通过 fileSystemWatcherFactory 创建一个新的文件监控,当类路径的内容发生变化时(不需要考虑是否需要重启,因为已经停止,并且没启动成功)就尝试重新启动。这种策略可以解决当配置或者代码出错无法启动时,可以修改BUG解决错误,然后 devtools 自动尝试启动。

FileWatchingFailureHandler 中的 FileSystemWatcher 和 3.2.3 中的不是同一个,并且在重启前另一个已经关闭,关闭的目的不是为了防止和这里存在两个监控出现冲突,而是为了防止第一次修改后,还没有重启时又发生了变化,由于重启需要时间,这就会导致重启还没完成就又重启了,这种情况下除了会产生错误外,还会因为短时间内频繁重启导致重启时间过长。Java架构交流学习圈:874811168 面向1-3年经验 Java开发人员 帮助突破瓶颈 提升思维能力

在重启时,会先关闭所有的 Spring Context,此时也会触发 ClassPathFileSystemWatcher 中的 destroy 方法:


在 destroy 中也会关闭文件监控,所以无论如何都不会和这里的 FileSystemWatcher 产生冲突。

3.3 重启后会重新初始化 Spring

关闭再启动时,devtools 通过反射执行的我们自己的 XXApplication 类的 main 方法,因此 LocalDevToolsAutoConfiguration 也会重新初始化,类路径监控也会重新建立。我们现在只是了解了从文件监控、类路径监控以及监控配置启动和触发重启的过程。有很多关键的处理过程和 RestartClassLoader 以及 Restarter 有关,为了防止过长篇幅使得关注点太过分散,后续会分别介绍这两部分内容。

转载于:https://blog.51cto.com/13982920/2312175

Spring Developer Tools 源码分析:三、重启自动配置'的更多相关文章

  1. Spring Developer Tools 源码分析:二、类路径监控

    在 Spring Developer Tools 源码分析一中介绍了 devtools 提供的文件监控实现,在第二部分中,我们将会使用第一部分提供的目录监控功能,实现对开发环境中 classpath ...

  2. Spring IOC 容器源码分析 - 填充属性到 bean 原始对象

    1. 简介 本篇文章,我们来一起了解一下 Spring 是如何将配置文件中的属性值填充到 bean 对象中的.我在前面几篇文章中介绍过 Spring 创建 bean 的流程,即 Spring 先通过反 ...

  3. Spring IOC 容器源码分析 - 循环依赖的解决办法

    1. 简介 本文,我们来看一下 Spring 是如何解决循环依赖问题的.在本篇文章中,我会首先向大家介绍一下什么是循环依赖.然后,进入源码分析阶段.为了更好的说明 Spring 解决循环依赖的办法,我 ...

  4. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  5. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  6. 十、Spring之BeanFactory源码分析(二)

    Spring之BeanFactory源码分析(二) 前言 在前面我们简单的分析了BeanFactory的结构,ListableBeanFactory,HierarchicalBeanFactory,A ...

  7. 九、Spring之BeanFactory源码分析(一)

    Spring之BeanFactory源码分析(一) ​ 注意:该随笔内容完全引自https://blog.csdn.net/u014634338/article/details/82865644,写的 ...

  8. tomcat源码分析(三)一次http请求的旅行-从Socket说起

    p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...

  9. Spring IOC 容器源码分析 - 余下的初始化工作

    1. 简介 本篇文章是"Spring IOC 容器源码分析"系列文章的最后一篇文章,本篇文章所分析的对象是 initializeBean 方法,该方法用于对已完成属性填充的 bea ...

随机推荐

  1. 家庭版记账本app开发完成

    经过这几天关于android的相关学习,对于家庭版记账本app以及开发结束. 实现的功能为:用户的注册.登录.添加支出账单.添加收入账单.显示所有的该用户的账单情况(收入和支出).生产图表(直观的显示 ...

  2. Linux网络架设篇,虚拟机l系统中网卡设备名与配置文件不符如何处理?

    很多情况下,当我们在虚拟机中安装好linux系统后,并不能成功连上网.当我们配置好相关IP地址后同样不能成功连接网络.并且会体会网卡名与配置名不符,这时候应该怎么办呢? 1.清空下面文件 /etc/u ...

  3. 33 File 文件及目录操作

    /* * File:文件和目录路径名的抽象表示形式,File 类的实例是不可变的 * * 构造方法: * File(String pathname) 将指定的路径名转换成一个File对象 * File ...

  4. 9.2ArrayList 集合 案例,学生管理系统

    循环的使用 添加学生:while嵌套for,for设置变量,内嵌if更新变量.if语句判断变量值 修改学生:for循环内嵌if,获取循环中的某个值. package day9_ArrayList.AL ...

  5. mysql添加,授权,删除用户以及连接数据库Can't connect to MySQL server on '192.168.31.106' (113)错误排查

    centos7下面操作mysql添加,授权,删除用户 添加用户 以root用户登录数据库,运行以下命令: create user test identified by '; 上面创建了用户test,密 ...

  6. redis中的缓存-缓存雪崩和缓存穿透

    缓存雪崩 缓存雪崩是由于原有缓存失效(过期),新缓存未到期间.所有请求都去查询数据库,而对数据库CPU和内存造成巨大压力,严重的会造成数据库宕机.从而形成一系列连锁反应,造成整个系统崩溃. 1. 碰到 ...

  7. AJ学IOS 之CoreLocation指南针小应用

    AJ分享,必须精品 一:效果图示 简单的用到CoreLocation获取方位做的指南针小应用 二:制作思路 具体用到了CoreLocation相关的知识,请看上一篇博客有写 然后获取方向不需要进行授权 ...

  8. AJ学IOS 之微博项目实战(2)微博主框架-自定义导航控制器NavigationController

    AJ分享,必须精品 一:添加导航控制器 上一篇博客完成了对底部的TabBar的设置,这一章我们完成自定义导航控制器(NYNavigationController). 为啥要做自定义呢,因为为了更好地封 ...

  9. 利用 Github 网络钩子实现自动化部署

    GitHub 的网络钩子(webhook)功能,可以很方便的实现自动化部署.本文记录了使用 Node.js 的开发部署过程,当项目的 master 分支被推时,将在服务器进行自动部署 添加网路钩子 在 ...

  10. C - Highways poj1751最小生成树

    The island nation of Flatopia is perfectly flat. Unfortunately, Flatopia has a very poor system of p ...