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

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
云解析 DNS,旗舰版 1个月
简介: 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实例化又发生在什么时候?

目录
打赏
0
0
0
0
34
分享
相关文章
DHCP与DNS的配置
通过这些步骤,您可以在Linux环境下成功配置和验证DHCP和DNS服务。希望这些内容对您的学习和工作有所帮助。
96 27
springcloud/springboot集成NACOS 做注册和配置中心以及nacos源码分析
通过本文,我们详细介绍了如何在 Spring Cloud 和 Spring Boot 中集成 Nacos 进行服务注册和配置管理,并对 Nacos 的源码进行了初步分析。Nacos 作为一个强大的服务注册和配置管理平台,为微服务架构提供
279 14
详细介绍SpringBoot启动流程及配置类解析原理
通过对 Spring Boot 启动流程及配置类解析原理的深入分析,我们可以看到 Spring Boot 在启动时的灵活性和可扩展性。理解这些机制不仅有助于开发者更好地使用 Spring Boot 进行应用开发,还能够在面对问题时,迅速定位和解决问题。希望本文能为您在 Spring Boot 开发过程中提供有效的指导和帮助。
77 12
|
5月前
|
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
93 4
手写模拟Spring Boot自动配置功能
【11月更文挑战第19天】随着微服务架构的兴起,Spring Boot作为一种快速开发框架,因其简化了Spring应用的初始搭建和开发过程,受到了广大开发者的青睐。自动配置作为Spring Boot的核心特性之一,大大减少了手动配置的工作量,提高了开发效率。
86 0
2025年阿里云弹性裸金属服务器架构解析与资源配置方案
🚀 核心特性与技术创新:提供100%物理机性能输出,支持NVIDIA A100/V100 GPU直通,无虚拟化层损耗。网络与存储优化,400万PPS吞吐量,ESSD云盘IOPS达100万,RDMA延迟<5μs。全球部署覆盖华北、华东、华南及海外节点,支持跨地域负载均衡。典型应用场景包括AI训练、科学计算等,支持分布式训练和并行计算框架。弹性裸金属服务器+OSS存储+高速网络综合部署,满足高性能计算需求。
|
5月前
|
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
95 0
SpringBoot自动配置及自定义Starter
Java程序员依赖Spring框架简化开发,但复杂的配置文件增加了负担。SpringBoot以“约定大于配置”理念简化了这一过程,通过引入各种Starter并加载默认配置,几乎做到开箱即用。
150 10
SpringBoot自动配置及自定义Starter
SpringBoot配置跨模块扫描问题解决方案
在分布式项目中,使用Maven进行多模块开发时,某些模块(如xxx-common)没有启动类。如何将这些模块中的类注册为Spring管理的Bean对象?本文通过案例分析,介绍了两种解决方案:常规方案是通过`@SpringBootApplication(scanBasePackages)`指定扫描路径;推荐方案是保持各模块包结构一致(如com.xxx),利用SpringBoot默认扫描规则自动识别其他模块中的组件,简化配置。
SpringBoot配置跨模块扫描问题解决方案
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
248 14

热门文章

最新文章

推荐镜像

更多
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等