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

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

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

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

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

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接口做了哪些事情,主要是看两个方法:

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

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

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

  13. //获取Spring容器要扫描的包
  14. protected Set<String> getComponentScanningPackages(
  15. BeanDefinitionRegistry registry) {
  16. Set<String> packages = new LinkedHashSet<String>();
  17. String[] names = registry.getBeanDefinitionNames();
  18. for (String name : names) {
  19. BeanDefinition definition = registry.getBeanDefinition(name);
  20. if (definition instanceof AnnotatedBeanDefinition) {
  21. AnnotatedBeanDefinition annotatedDefinition = (AnnotatedBeanDefinition) definition;
  22. addComponentScanningPackages(packages,
  23. annotatedDefinition.getMetadata()); //从每个definition中获取要扫描的包,并加入到packages集合中
  24. }
  25. }
  26. return packages;
  27. }

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

  1. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
  2. throws BeansException {
  3. for (Check check : this.checks) {
  4. String message = check.getWarning(registry);
  5. if (StringUtils.hasLength(message)) {
  6. warn(message);
  7. }
  8. }
  9.  
  10. }

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. docker mesos集群资源调度平台

    mesos原理与架构 首先,再次需要强调 Mesos 自身只是一个资源调度框架,并非一整套完整的应用管理平台,所以只有 Mesos 自己是不能干活的.但是基于 Mesos,可以比较容易地为各种应用管理 ...

  2. Arduino、bootloader、BadUSB、及其相关硬件知识入门学习

    内容中包含 base64string 图片造成字符过多,拒绝显示

  3. Docker: 安装配置入门[二]

    一.安装配置启动 1.环境 [root@docker1 ~]# cat /etc/redhat-release CentOS Linux release 7.4.1708 (Core) [root@d ...

  4. JAVA-集合类型List(ArrayList、LinkedList)常用操作例子(基础必备)

    package com.net.xinfang.reflect; import java.util.ArrayList; import java.util.Arrays; import java.ut ...

  5. SqlServer中的事务使用

    一.事务的概念和特点 事务(transaction)是恢复和并发控制的基本单位. 事务的特点 原子性:事务是一个工作单元,要都成功,要么的失败 例子:A付款给B,A余额-100,B余额+100,只能都 ...

  6. Jpush极光推送

    require 'jpush' class SidkiqJpushWorker include Sidekiq::Worker # args[0] msg : args[1] region_id ; ...

  7. DirectX11 With Windows SDK--02 顶点/像素着色器的创建、顶点缓冲区

    前言 由于在Direct3D 11中取消了固定管线,要想绘制图形必须要了解可编程渲染管线的流程,一个能绘制出图形的渲染管线最少需要有这两个可编程着色器:顶点着色器和像素着色器. 本章会直接跳过渲染管线 ...

  8. Part-Ten

    1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12.

  9. c# 三种传参方式 in,out,ref

    in:默认方式,传值不返回 out:不传值 但是会返回新值给予传参对象 ref:传存储地址,所以传参前必须赋值初始化,传值后的运算结果直接作用在传参上 Out和ref的效果差不多

  10. Android获取版本号

    public static String getVersionName(Context context) { PackageManager manager = context.getPackageMa ...