SpringBoot之自动配置类的解析和过滤机制

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 1.提炼三句话整体来讲Spring Boot是通过条件注解、条件评估器和自动配置导入器等机制来实现自动配置的。条件评估器来判断是否需要加载某个自动配置类。条件评估器通常被定义在“org.springframework.boot.autoconfigure.condition”包中,例如,ClassCondition、BeanCondition、MissingBeanCondition、WebApplicationCondition等条件注解来判断是否需要加载某个自动配置类。条件注解通常被定义在“org.springframework.boot.autoconfigure.conditi

1.提炼三句话

整体来讲Spring Boot是通过条件注解、条件评估器和自动配置导入器等机制来实现自动配置的。


条件评估器来判断是否需要加载某个自动配置类。条件评估器通常被定义在“org.springframework.boot.autoconfigure.condition”包中,例如,ClassCondition、BeanCondition、MissingBeanCondition、WebApplicationCondition等

条件注解来判断是否需要加载某个自动配置类。条件注解通常被定义在“org.springframework.boot.autoconfigure.condition”包中,例如,@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnWebApplication等。

自动配置导入器是用来来自动导入相关的自动配置类。自动配置导入器通常被定义在“org.springframework.boot.autoconfigure”包中,例如,JpaBaseConfiguration、DataSourcePoolMetadataProvidersConfiguration、HibernateJpaAutoConfiguration等

2. 详解

Spring Boot自动配置是一项强大的功能,它可以根据classpath下的类自动配置应用程序上下文。Spring Boot自动配置实际上是一组自定义的Spring Bean定义,它们可以通过自动扫描被发现并加载到容器中。


Spring Boot自动配置类通常被定义在“org.springframework.boot.autoconfigure”包中,并以“XxxAutoConfiguration”命名。Spring Boot提供了很多默认的自动配置类,例如,Spring MVC自动配置类(WebMvcAutoConfiguration)、JPA自动配置类(JpaBaseConfiguration)、数据源自动配置类(DataSourceAutoConfiguration)等。


Spring Boot通过一系列机制来实现自动配置,包括条件注解、条件评估器和自动配置导入器。下面我们来详细了解一下这些机制的源码实现。

2.1 条件注解

Spring Boot通过条件注解来判断是否需要加载某个自动配置类。条件注解通常被定义在“org.springframework.boot.autoconfigure.condition”包中,例如,@ConditionalOnClass、@ConditionalOnBean、@ConditionalOnMissingBean、@ConditionalOnWebApplication等。


例如,下面是一个基于@ConditionalOnClass注解的自动配置类:

@Configuration  
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})  
@EnableConfigurationProperties(DataSourceProperties.class)  
@AutoConfigureAfter({DataSourcePoolMetadataProvidersConfiguration.class,  
        HibernateJpaAutoConfiguration.class})  
public class DataSourceAutoConfiguration {  
    // 自动配置代码...  
}  

自动配置类会在classpath中存在DataSource和EmbeddedDatabaseType类时被加载。

2.2 条件评估器

Spring Boot通过条件评估器来判断是否需要加载某个自动配置类。条件评估器通常被定义在“org.springframework.boot.autoconfigure.condition”包中,例如,ClassCondition、BeanCondition、MissingBeanCondition、WebApplicationCondition等。

例如基于ClassCondition的条件评估器:

public class OnClassCondition extends FilteringSpringBootCondition {  
    // ...  
    protected boolean matches(Class<?> type) {  
        return this.beanFactory.getBeanNamesForType(type, true, false).length > 0;  
    }  
    // ...  
}  

条件评估器会判断当前应用程序上下文中是否存在指定类型的Bean。

2.3 自动配置导入器

通过自动配置导入器来自动导入相关的自动配置类。自动配置导入器通常被定义在“org.springframework.boot.autoconfigure”包中,例如,JpaBaseConfiguration、DataSourcePoolMetadataProvidersConfiguration、HibernateJpaAutoConfiguration等。

例如基于@Import注解的自动配置导入器:

@Configuration  
@ConditionalOnClass({LocalContainerEntityManagerFactoryBean.class, EnableJpaRepositories.class})  
@EnableConfigurationProperties(JpaProperties.class)  
@Import({JpaBaseConfiguration.class,  
        HibernateJpaAutoConfiguration.class})  
public class HibernateJpaConfiguration {  
    // 自动配置代码...  
}  

自动配置导入器会导入JpaBaseConfiguration和HibernateJpaAutoConfiguration两个自动配置类。


Spring Boot通过条件注解、条件评估器和自动配置导入器等机制来实现自动配置。这些机制可以帮助开发人员快速构建应用程序,减少重复的配置工作。

3.学以致用

Spring Boot 的自动配置类是一个非常强大的特性,它可以根据项目中的依赖和配置自动配置应用程序的环境,从而让开发者更加专注于业务逻辑的实现。

在实际项目中,我们可以通过自定义自动配置类来实现一些特定的需求,或者通过过滤机制来排除一些不需要的自动配置类。


使用场景和示例代码

1. 自定义自动配置类

假设我们的项目需要使用一个名为 MyService 的服务,我们可以定义一个自动配置类 MyServiceAutoConfiguration,它可以根据项目的配置来初始化 MyService 实例。具体代码如下:

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
public class MyServiceAutoConfiguration {
  @Autowired  
  private MyServiceProperties properties;
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  

在上面的代码中,我们使用了@EnableConfigurationProperties 注解来启用 MyServiceProperties 配置类,并且使用@ConditionalOnClass 注解来判断 MyService 是否在类路径上可用。在@Bean 方法中,我们使用了@ConditionalOnMissingBean 注解来判断当前应用程序上下文中是否已经存在 MyService 实例,如果不存在,则创建一个新的实例。

2. 排除不需要的自动配置类

有时候我们可能不需要某些自动配置类,比如我们不需要使用 Spring Boot 的数据库自动配置,我们可以通过在 application.properties 文件中设置 exclude 属性来排除它。具体代码如下:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration  

在上面的配置中,通过设置 spring.autoconfigure.exclude 属性来排除 DataSourceAutoConfiguration 类,从而禁用 Spring Boot 的数据库自动配置。

3. 使用条件注解控制自动配置

有时候我们可能需要根据特定的条件来控制自动配置是否生效,比如根据某个属性的值来判断是否需要配置某个组件。在这种情况下,我们可以使用@ConditionalXXX 注解来控制自动配置,这些注解都是继承自 Spring 提供的 Condition 接口的。

例如,可以根据 application.properties 中的一个属性来控制是否需要配置 MyService 实例,具体代码如下:

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
@ConditionalOnProperty(prefix = "myservice", name = "enabled", havingValue = "true", matchIfMissing = true)  
public class MyServiceAutoConfiguration {
  @Autowired  
  private MyServiceProperties properties;
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  

使用@ConditionalOnProperty 注解来判断是否需要配置 MyService 实例,prefix 参数指定属性的前缀,name 参数指定属性的名称,havingValue 参数指定属性的值,matchIfMissing 参数指定当属性不存在时的默认值。

4. 自定义属性配置类

这个在我们的项目中是很常见的,我就不赘述了

使用 MyServiceProperties 配置类来获取 application.properties 中的配置,这个配置类需要使用@EnableConfigurationProperties 注解来启用。如果想要更加灵活地控制该配置类的加载,可以使用@ConfigurationProperties 注解来标记这个配置类,并且使用@ImportResource 注解来加载配置文件。


例如可将 MyServiceProperties 配置类的配置文件单独放在一个 myservice.properties 文件中,并且使用@ConfigurationProperties 注解来加载该文件,代码如下:

@Configuration  
@ImportResource("classpath:/myservice.properties")  
@ConfigurationProperties(prefix = "myservice")  
public class MyServiceProperties {  
  private String host;  
  private int port;  
  // getters and setters  
}  

5. 自定义自动配置类的优先级

每个自动配置类都有一个优先级,优先级越高的自动配置类会优先生效。想要自定义自动配置类的优先级,可以使用@AutoConfigureOrder 注解来指定。

例如可以将 MyServiceAutoConfiguration 的优先级设置为 1,使它比其他自动配置类优先生效,具体代码如下:

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)  
public class MyServiceAutoConfiguration {
  @Autowired  
  private MyServiceProperties properties;
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  

 

6. 自定义自动配置类的加载顺序

自动配置类的加载顺序默认是按照字母顺序来决定的(可以看源码剖析部分)。如果想要自定义自动配置类的加载顺序,可以使用@AutoConfigureAfter 和@AutoConfigureBefore 注解来指定。

例如,可以将 MyServiceAutoConfiguration 设置为在 DataSourceAutoConfiguration 之后加载,代码如下:

使用@AutoConfigureAfter 注解将 MyServiceAutoConfiguration 设置为在 DataSourceAutoConfiguration 之后加载。

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
@AutoConfigureAfter(DataSourceAutoConfiguration.class)  
public class MyServiceAutoConfiguration {
  @Autowired  
  private MyServiceProperties properties;
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  

自定义优先级和加载顺序可以帮助我们更加灵活地控制自动配置。在实际项目中大家可以自由发挥。

7. 自定义自动配置类的条件

在 Spring Boot 中可以使用条件注解来控制自动配置类的加载条件。除了 Spring Boot 提供的条件注解之外,还可以自定义条件注解来控制自动配置类的加载条件。

自定义一个@ConditionalOnMyCondition 注解来控制某个自动配置类的加载条件,代码如下:

@Target({ ElementType.TYPE, ElementType.METHOD })  
@Retention(RetentionPolicy.RUNTIME)  
@Conditional(MyCondition.class)  
public @interface ConditionalOnMyCondition {
  String value();
}  

然后,在自动配置类中使用@ConditionalOnMyCondition 注解来控制加载条件,具体代码如下:

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
@ConditionalOnMyCondition("my.condition.enabled")  
public class MyServiceAutoConfiguration {
  @Autowired  
  private MyServiceProperties properties;
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  

8. 自定义自动配置类的条件类

除了自定义条件注解之外还可以自定义条件类来控制自动配置类的加载条件。条件类需要实现 Condition 接口,并且实现 matches 方法。

例如可以定义一个 MyCondition 条件类来控制某个自动配置类的加载条件,具体代码如下:

定义一个 MyCondition 条件类,并且实现了 matches 方法来判断是否满足加载条件。当 application.properties 中的 my.condition.enabled 属性为 true 时,才会加载这个自动配置类。

public class MyCondition implements Condition {  
  @Override  
  public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {  
    String enabled = context.getEnvironment().getProperty("my.condition.enabled");  
    return Boolean.parseBoolean(enabled);  
  }  
}  

然后,在自动配置类中使用@Conditional 注解来指定 MyCondition 条件类,具体代码如下:

@Configuration  
@EnableConfigurationProperties(MyServiceProperties.class)  
@ConditionalOnClass(MyService.class)  
@Conditional(MyCondition.class)  
public class MyServiceAutoConfiguration {  
  @Autowired  
  private MyServiceProperties properties;  
  @Bean  
  @ConditionalOnMissingBean(MyService.class)  
  public MyService myService() {  
    return new MyService(properties.getHost(), properties.getPort());  
  }  
}  


目录
相关文章
|
1月前
|
数据可视化 数据挖掘 BI
团队管理者必读:高效看板类协同软件的功能解析
在现代职场中,团队协作的效率直接影响项目成败。看板类协同软件通过可视化界面,帮助团队清晰规划任务、追踪进度,提高协作效率。本文介绍看板类软件的优势,并推荐五款优质工具:板栗看板、Trello、Monday.com、ClickUp 和 Asana,助力团队实现高效管理。
57 2
|
2月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
121 2
|
20天前
|
机器学习/深度学习 自然语言处理 搜索推荐
自注意力机制全解析:从原理到计算细节,一文尽览!
自注意力机制(Self-Attention)最早可追溯至20世纪70年代的神经网络研究,但直到2017年Google Brain团队提出Transformer架构后才广泛应用于深度学习。它通过计算序列内部元素间的相关性,捕捉复杂依赖关系,并支持并行化训练,显著提升了处理长文本和序列数据的能力。相比传统的RNN、LSTM和GRU,自注意力机制在自然语言处理(NLP)、计算机视觉、语音识别及推荐系统等领域展现出卓越性能。其核心步骤包括生成查询(Q)、键(K)和值(V)向量,计算缩放点积注意力得分,应用Softmax归一化,以及加权求和生成输出。自注意力机制提高了模型的表达能力,带来了更精准的服务。
|
24天前
|
JavaScript Java 程序员
SpringBoot自动配置及自定义Starter
Java程序员依赖Spring框架简化开发,但复杂的配置文件增加了负担。SpringBoot以“约定大于配置”理念简化了这一过程,通过引入各种Starter并加载默认配置,几乎做到开箱即用。
81 10
SpringBoot自动配置及自定义Starter
|
1月前
|
Java Maven Spring
SpringBoot配置跨模块扫描问题解决方案
在分布式项目中,使用Maven进行多模块开发时,某些模块(如xxx-common)没有启动类。如何将这些模块中的类注册为Spring管理的Bean对象?本文通过案例分析,介绍了两种解决方案:常规方案是通过`@SpringBootApplication(scanBasePackages)`指定扫描路径;推荐方案是保持各模块包结构一致(如com.xxx),利用SpringBoot默认扫描规则自动识别其他模块中的组件,简化配置。
SpringBoot配置跨模块扫描问题解决方案
|
1月前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
119 14
|
2月前
|
缓存 IDE Java
SpringBoot入门(7)- 配置热部署devtools工具
SpringBoot入门(7)- 配置热部署devtools工具
108 1
SpringBoot入门(7)- 配置热部署devtools工具
|
2月前
|
存储 缓存 监控
后端开发中的缓存机制:深度解析与最佳实践####
本文深入探讨了后端开发中不可或缺的一环——缓存机制,旨在为读者提供一份详尽的指南,涵盖缓存的基本原理、常见类型(如内存缓存、磁盘缓存、分布式缓存等)、主流技术选型(Redis、Memcached、Ehcache等),以及在实际项目中如何根据业务需求设计并实施高效的缓存策略。不同于常规摘要的概述性质,本摘要直接点明文章将围绕“深度解析”与“最佳实践”两大核心展开,既适合初学者构建基础认知框架,也为有经验的开发者提供优化建议与实战技巧。 ####
|
1月前
|
PHP 开发者 UED
PHP中的异常处理机制解析####
本文深入探讨了PHP中的异常处理机制,通过实例解析try-catch语句的用法,并对比传统错误处理方式,揭示其在提升代码健壮性与可维护性方面的优势。文章还简要介绍了自定义异常类的创建及其应用场景,为开发者提供实用的技术参考。 ####
|
2月前
|
缓存 NoSQL Java
千万级电商线上无阻塞双buffer缓冲优化ID生成机制深度解析
【11月更文挑战第30天】在千万级电商系统中,ID生成机制是核心基础设施之一。一个高效、可靠的ID生成系统对于保障系统的稳定性和性能至关重要。本文将深入探讨一种在千万级电商线上广泛应用的ID生成机制——无阻塞双buffer缓冲优化方案。本文从概述、功能点、背景、业务点、底层原理等多个维度进行解析,并通过Java语言实现多个示例,指出各自实践的优缺点。希望给需要的同学提供一些参考。
62 8

热门文章

最新文章

推荐镜像

更多