SpringBoot自动配置原理解析(一)

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介: SpringBoot自动配置原理解析(一)

关联博文:

SpringBoot自动配置原理解析(一)

SpringBoot自动配置原理解析(二)


SpringBoot自动配置原理解析(三)

SpringBoot自动配置原理解析(四)

SpringBoot自动配置原理解析(五)


本文我们开始分析SpringBoot的自动配置原理。当我们想使用某个中间件时比如Redis,我们直接引入其starter然后在application.properties做一些简单配置即可使用。这就是SpringBoot的自动配置在起作用。


从本质来讲,自动配置无非就是有个处理器在启动流程的某个环节根据某个条件进行了自动扫描并注册BeanDefinition到BeanFactory中。那么这里我们要搞清楚这样几个问题:


表现是什么?

处理器是什么?

哪个环节?

如何扫描注册?

什么时候实例化?

我们先从@SpringBootApplication这个注解看起。


@SpringBootApplication


如下所示,该注解是一个复合注解其上面标注了@SpringBootConfiguration@EnableAutoConfiguration。这里也标注了@ComponentScan注解表明以当前类所在包为基础进行扫描、注册并实例化。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
  //...
}


① @SpringBootConfiguration

SpringBootConfiguration注解如下所示,其使用了@Configuration注解进行标注表明其是一个配置类。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
  // 标明@Configuration标注的类中那些@Bean标注的方法是否应该被代理,默认为true
  @AliasFor(annotation = Configuration.class)
  boolean proxyBeanMethods() default true;
}


@Configuration注解也是一个复合注解,其又被@Component标注,表明配置类也是一个普通组件可以被扫描、注入到容器中。我们回过头继续看另外一个注解@EnableAutoConfiguration

② @EnableAutoConfiguration


这个注解是用来干嘛的呢?简单来讲就是启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean。自动配置类通常基于类路径和定义的bean来应用。例如,如果在类路径上有tomcat-embedded.jar,则可能需要一个TomcatServletWebServerFactory(除非定义了自己的ServletWebServerFactory bean)。


通常通过@SpringBootApplication 标注@EnableAutoConfiguration注解的包具有特定的意义,通常用作“默认值”。例如,它将在扫描@Entity类时使用。通常建议将@EnableAutoConfiguration(如果没有使用@SpringBootApplication)放在根包中,以便可以搜索所有子包和类。


Auto-configuration(自动配置)类也是常规的Spring Configuration bean,它们被spring的SpringFactoriesLoader机制进行加载(通过配置文件spring.factories配置的EnableAutoConfiguration属性值)。

通常自动配置类被标注了@Conditional注解,大多数情况还会存在@ConditionalOnClass@ConditionalOnMissingBean注解。用来判断当前自动配置类生效的时机。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
  String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
   // 排除具体的自动配置类
  Class<?>[] exclude() default {};
   // 排除具体的配置类,这里返回类名称数组
  String[] excludeName() default {};
}


也就是说只要我们应用中有了这样一个标注了@EnableAutoConfiguration 的主启动类,SpringBoot就可以启用自动配置流程完成扫描并加载、注册相关的BeanDefinition到容器中。那么SpringBoot从哪里扫描得到自动配置类信息?


我们回过头继续看注解。@Import注解是一个导入注解,允许导入标注了@Configuration的类、ImportSelector、ImportBeanDefinitionRegistrar以及其他常规组件(类似于AnnotationConfigApplicationContext#register)。这里导入了AutoConfigurationImportSelector这个组件,这个组件很重要。


@AutoConfigurationPackage注解呢,是一个复合注解被@Import(AutoConfigurationPackages.Registrar.class)标注导入了AutoConfigurationPackages.Registrar

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import(AutoConfigurationPackages.Registrar.class)
public @interface AutoConfigurationPackage {
}


如下图所示,在AutoConfigurationImportSelectorgetCandidateConfigurations方法中会从META-INF/spring.factories配置文件中扫描那些EnableAutoConfiguration配置类。


spring-boot-autoconfigure-2.2.4.RELEASE.jar!\META-INF\spring.factories中,我们能够看到如下配置。



其中就有RedisAutoConfiguration,其自动配置类如下所示,这也是我们为什么直接简洁配置就可以使用Redis的原因。

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {
  @Bean
  @ConditionalOnMissingBean(name = "redisTemplate")
  public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
      throws UnknownHostException {
    RedisTemplate<Object, Object> template = new RedisTemplate<>();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }
  @Bean
  @ConditionalOnMissingBean
  public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
      throws UnknownHostException {
    StringRedisTemplate template = new StringRedisTemplate();
    template.setConnectionFactory(redisConnectionFactory);
    return template;
  }
}


而AutoConfigurationPackages.Registrar是用来做什么呢?

其本身实现了ImportBeanDefinitionRegistrar,重写了registerBeanDefinitions。也就说这个类主要用来注册BeanDefinition到BeanFactory中。注册了什么BeanDefinition?如下图所示以编程方式注册自动配置包名称,其中包名是从@EnableAutoConfiguration配置类设置的。



a5f3e6ba951a44d0b273b011b02a730b.png


到了这里,我们就从表现上看到了自动配置注解、配置类扫描、bean定义的注解。

那么扫描、注册BeanDefinition发生在哪个环节呢?哪个处理器来执行的呢?bean实例化又发生在什么时候?

目录
相关文章
|
7小时前
|
数据采集 消息中间件 监控
Flume数据采集系统设计与配置实战:面试经验与必备知识点解析
【4月更文挑战第9天】本文深入探讨Apache Flume的数据采集系统设计,涵盖Flume Agent、Source、Channel、Sink的核心概念及其配置实战。通过实例展示了文件日志收集、网络数据接收、命令行实时数据捕获等场景。此外,还讨论了Flume与同类工具的对比、实际项目挑战及解决方案,以及未来发展趋势。提供配置示例帮助理解Flume在数据集成、日志收集中的应用,为面试准备提供扎实的理论与实践支持。
37 1
|
7小时前
|
安全 Java 开发者
深入理解Spring Boot配置绑定及其实战应用
【4月更文挑战第10天】本文详细探讨了Spring Boot中配置绑定的核心概念,并结合实战示例,展示了如何在项目中有效地使用这些技术来管理和绑定配置属性。
11 1
|
7小时前
|
Java 文件存储 Spring
【springboot】logback配置
【springboot】logback配置
19 1
|
7小时前
|
缓存 测试技术 Android开发
深入了解Appium:Capability 高级配置技巧解析
Appium 提供多种进阶配置项以优化自动化测试,如 deviceName 作为设备别名,udid 确保选择特定设备,newCommandTimeout 设置超时时间,PRINT_PAGE_SOURCE_ON_FIND_FAILURE 在错误时打印页面源,以及测试策略中的 noReset、shouldTerminateApp 和 forceAppLaunch 控制应用状态和重启。这些配置可提升测试效率和准确性。
17 2
|
7小时前
|
存储 弹性计算 固态存储
阿里云服务器配置选择指南,2024年全解析
阿里云服务器配置选择涉及CPU、内存、带宽和磁盘。个人开发者或中小企业推荐使用轻量应用服务器或ECS经济型实例,如2核2G3M配置,适合网站和轻量应用。企业用户则应选择企业级独享型ECS,如计算型c7、通用型g7,至少2核4G起,带宽建议5M,系统盘考虑SSD云盘或ESSD云盘以保证性能。阿里云提供了多种实例类型和配置,用户需根据实际需求进行选择。
|
7小时前
|
Java 微服务 Spring
Spring Boot中获取配置参数的几种方法
Spring Boot中获取配置参数的几种方法
22 2
|
7小时前
|
分布式计算 DataWorks 调度
DataWorks操作报错合集之DataWorks配置参数在开发环境进行调度,参数解析不出来,收到了 "Table does not exist" 的错误,该怎么处理
DataWorks是阿里云提供的一站式大数据开发与治理平台,支持数据集成、数据开发、数据服务、数据质量管理、数据安全管理等全流程数据处理。在使用DataWorks过程中,可能会遇到各种操作报错。以下是一些常见的报错情况及其可能的原因和解决方法。
25 0
|
7小时前
|
Web App开发 前端开发 Java
SpringBoot配置HTTPS及开发调试
在实际开发过程中,如果后端需要启用https访问,通常项目启动后配置nginx代理再配置https,前端调用时高版本的chrome还会因为证书未信任导致调用失败,通过摸索整理一套开发调试下的https方案,特此分享
20 0
SpringBoot配置HTTPS及开发调试
|
7小时前
|
分布式计算 大数据 数据处理
MaxCompute操作报错合集之在开发环境中配置MaxCompute参数进行调度,但参数解析不出来,如何解决
MaxCompute是阿里云提供的大规模离线数据处理服务,用于大数据分析、挖掘和报表生成等场景。在使用MaxCompute进行数据处理时,可能会遇到各种操作报错。以下是一些常见的MaxCompute操作报错及其可能的原因与解决措施的合集。
|
7小时前
|
监控 安全 网络协议

推荐镜像

更多