ConfigurationWarningsApplicationContextInitializer的作用是用来报告Spring容器的一些常见的错误配置的。这个类中定义了两个内部类:

1. 定义了一个Check接口及它的实现类ComponentScanPackageCheck(以静态内部类形式定义)

2. 定义了一个BeanDefinitionRegistryPostProcessor接口的实现类(以静态内部类形式定义)

因此我把这两个内部类理解成ConfigurationWarningsApplicationContextInitializer的组合成员,类图附在最后,

 initialize()方法,获取Check的实例,然后构建出一个ConfigurationWarningsPostProcessor实例,注册到Sring的容器中
public void initialize(ConfigurableApplicationContext context) {
context.addBeanFactoryPostProcessor(
new ConfigurationWarningsPostProcessor(getChecks()));
}

ConfigurationWarningsPostProcessor是BeanDefinitionRegistryPostProcessor接口的实现类,而BeanDefinitionRegistryPostProcessor接口又继承于BeanFactoryPostProcessor接口,下面依次了解下这几个Spring的接口和类图:

BeanFactoryPostProcessor接口:允许对spring容器的bean definition进行自定义的修改,可改变容器底层管理的bean的属性值。Spring容器会自动检测容器的bean definition中有没实现了BeanFactoryPostProcessor接口的Bean ,如果有话将会在创建其他Bean之前首先执行该接口的代码。

 BeanDefinitionRegistryPostProcessor接口:对BeanFactoryPostProcessor接口的一个扩展,允许在Spring容器会自动检测容器的bean definition之前,进一步的注册bean definiton到容器中。特定情况下还可以通过进一步的注册bean definiton而反过来定义BeanFactoryPostProcessor接口的实例

BeanDefinitionRegistry接口:作用主要是向注册表中注册 BeanDefinition 实例

搞清楚相关接口的用意后,我们看一下 ConfigurationWarningsPostProcessor 实现BeanDefinitionRegistryPostProcessor接口BeanFactoryPostProcessor接口做了哪些事情,主要是看两个方法:

        //这是实现BeanFactoryPostProcessor接口的方法,没做任何事
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
} //这个是实现BeanDefinitionRegistryPostProcessor接口的方法,主要是把在注册BeanDefinition实例过程中产生的告警信息传给Check接口的实例进行处理产生要告警的内容,没进行告警输出
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
for (Check check : this.checks) {
String message = check.getWarning(registry);
if (StringUtils.hasLength(message)) {
warn(message); //通过日志打印出告警信息
}
} }

由此可见 ConfigurationWarningsPostProcessor 的主要作用就是把在注册BeanDefinition实例过程中产生的告警信息传给Check接口的实例进行处理,ConfigurationWarningsApplicationContextInitializer中只提供了一个Check的实现 ComponentScanPackageCheck,简单分析下 ComponentScanPackageCheck类的源码:

        //这个方法是实现了Check接口的接口方法
public String getWarning(BeanDefinitionRegistry registry) {
Set<String> scannedPackages = getComponentScanningPackages(registry);
List<String> problematicPackages = getProblematicPackages(scannedPackages); //获取有在扫描包范围内的有警告的包
if (problematicPackages.isEmpty()) {
return null;
}
return "Your ApplicationContext is unlikely to "
+ "start due to a @ComponentScan of "
+ StringUtils.collectionToDelimitedString(problematicPackages, ", ")
+ ".";
}

//获取Spring容器要扫描的包
protected Set<String> getComponentScanningPackages(
BeanDefinitionRegistry registry) {
Set<String> packages = new LinkedHashSet<String>();
String[] names = registry.getBeanDefinitionNames();
for (String name : names) {
BeanDefinition definition = registry.getBeanDefinition(name);
if (definition instanceof AnnotatedBeanDefinition) {
AnnotatedBeanDefinition annotatedDefinition = (AnnotatedBeanDefinition) definition;
addComponentScanningPackages(packages,
annotatedDefinition.getMetadata()); //从每个definition中获取要扫描的包,并加入到packages集合中
}
}
return packages;
}

以下是打印告警信息的方法,这个方法 还是位于 ConfigurationWarningsPostProcessor 类中,这个方法会由Spring容器在检测处理BeanFactoryPostProcessor接口的bean definition时触发并执行:

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
for (Check check : this.checks) {
String message = check.getWarning(registry);
if (StringUtils.hasLength(message)) {
warn(message);
}
} }

Spring Boot默认Initializer(1)——ConfigurationWarningsApplicationContextInitializer的更多相关文章

  1. Spring Boot默认的JSON解析框架设置

    方案一:启动类继承WebMvcConfigurerAdapter,覆盖方法configureMessageConverters ... @SpringBootApplication public cl ...

  2. spring boot默认访问静态资源

    演示spring boot默认可以直接访问静态资源的2种方法: 第一种:在src/main/resources资源目录下创建一个名为"static"的文件夹(该文件夹的名称是规定死 ...

  3. Spring boot 默认静态资源路径与手动配置访问路径的方法

    这篇文章主要介绍了Spring boot 默认静态资源路径与手动配置访问路径的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下   在application.propertis中配置 ##端口号 ...

  4. Spring Boot 默认指标从哪来?

    了解有关 Spring Boot 默认指标及其来源的更多信息. 您是否注意到 Spring Boot 和 Micrometer 为您的应用生成的所有默认指标? 如果没有 - 您可以将 actuator ...

  5. Spring Boot默认日志logback配置解析

    前言 今天来介绍下Spring Boot如何配置日志logback,我刚学习的时候,是带着下面几个问题来查资料的,你呢 如何引入日志? 日志输出格式以及输出方式如何配置? 代码中如何使用? 正文 Sp ...

  6. Spring Boot 默认的指标数据从哪来的?

    了解有关 Spring Boot 默认指标及其来源的更多信息. 您是否注意到 Spring Boot 和 Micrometer 为您的应用生成的所有默认指标?如果没有 - 您可以将 actuator  ...

  7. 20. Spring Boot 默认、自定义数据源 、配置多个数据源 jdbcTemplate操作DB

    Spring-Boot-2.0.0-M1版本将默认的数据库连接池从tomcat jdbc pool改为了hikari,这里主要研究下hikari的默认配置 0.  创建Spring Boot项目,选中 ...

  8. 修改Spring Boot默认的上下文

    前言 默认情况下,Spring Boot使用的服务上下文为"/",我们可以通过"http://localhost:PORT/" 直接诶访问应用: 但是在生产环境 ...

  9. 【杂谈】Spring Boot 默认支持的并发量

    Spring Boot应用支持的最大并发量是多少? Spring Boot 能支持的最大并发量主要看其对Tomcat的设置,可以在配置文件中对其进行更改.当在配置文件中敲出max后提示值就是它的默认值 ...

随机推荐

  1. NandFlash学习

    目录 NandFlash学习 概述 原理图(K9F2G08U0C) 启动的引脚配置 命令概述 操作概述 Uboot下操作体验 ID与地址编码 时序初始化 程序设计 忙判断 基本操作 读NAND 擦除 ...

  2. 15、JDBC-CallableStatement

    一.存储过程 创建 CREATE DEFINER=CURRENT_USER PROCEDURE `adder`(IN a int, IN b int, OUT sum int) BEGIN DECLA ...

  3. 微信小程序遇到的知识点

    话不多说,都是干货!!! 页面的生命周期: 当打开一个页面的时候,会触发onLoad和onReady和onShow事件. onLoad和onReady只触发一次.除非卸载了页面就是触发了onUnloa ...

  4. Accord.NET Framework 介绍

    阅读目录 1.基本功能与介绍 Accord.NET Framework是在AForge.NET项目的基础上封装和进一步开发而来.因为AForge.NET更注重与一些底层和广度,而Accord.NET  ...

  5. PHP7 学习笔记(十二)PHPExcel vs PhpSpreadsheet and PHP_XLSXWriter

    前言 PhpSpreadsheet是PHPExcel的下一个版本. 它打破了兼容性,极大地提高了代码库的质量(命名空间,PSR合规性,使用最新的PHP语言功能等).由于所有努力都转移到了PhpSpre ...

  6. Redis基本概念、基本使用与单机集群部署

    1. Redis基础 1.1 Redis概述 Redis是一个开源.先进的key-value存储,并用于构建高性能.可扩展的应用程序的完美解决方案. Redis从它的许多竞争继承了三个主要特点:    ...

  7. http的三次握手四次挥手

    http : 是一种超文本传输协议 传输指的是在客户端和服务器之间进行传输数据 http不仅仅可以传输文本,还可以传输图片.音频.视频等内容 https : 是一种更加安全的传输协议 在普通的传输协议 ...

  8. C# Math.Round实现中国式四舍五入

    decimal sum = 11111.334; sum = , MidpointRounding.AwayFromZero);  sum:11111.33decimal sum = 11111.34 ...

  9. CSS样式选择

    1:#a,b{…………}一个id叫a和一个标签是b的样式 2:#a b{…………}一个id叫a下面的一个标签是b的样式3:#a:b{…………}一个id叫a的伪类b的样式4:#a.b{…………}一个id ...

  10. 四十一、Linux 线程——线程同步之条件变量

    41.1 概念 41.1.1 条件变量的介绍 互斥锁的缺点是它只有两种状态:锁定和非锁定 条件变量通过允许线程阻塞和等待另一个线程发送信号的方法弥补了互斥锁的不足 条件变量内部是一个等待队列,放置等待 ...