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

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 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());  
  }  
}  


目录
相关文章
|
24天前
|
Java API 数据库
构建RESTful API已经成为现代Web开发的标准做法之一。Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐。
【10月更文挑战第11天】本文介绍如何使用Spring Boot构建在线图书管理系统的RESTful API。通过创建Spring Boot项目,定义`Book`实体类、`BookRepository`接口和`BookService`服务类,最后实现`BookController`控制器来处理HTTP请求,展示了从基础环境搭建到API测试的完整过程。
36 4
|
21天前
|
Java API 数据库
Spring Boot框架因其简洁的配置、快速的启动特性及丰富的功能集而备受开发者青睐
本文通过在线图书管理系统案例,详细介绍如何使用Spring Boot构建RESTful API。从项目基础环境搭建、实体类与数据访问层定义,到业务逻辑实现和控制器编写,逐步展示了Spring Boot的简洁配置和强大功能。最后,通过Postman测试API,并介绍了如何添加安全性和异常处理,确保API的稳定性和安全性。
31 0
|
8天前
|
Java Spring 容器
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
SpringBoot读取配置文件的6种方式,包括:通过Environment、@PropertySource、@ConfigurationProperties、@Value读取配置信息
30 3
|
13天前
|
域名解析 存储 缓存
DNS是什么?内网电脑需要配置吗?
【10月更文挑战第22天】DNS是什么?内网电脑需要配置吗?
48 1
|
19天前
|
druid Java Maven
|
15天前
|
存储 Java API
详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
【10月更文挑战第19天】深入剖析Java Map:不仅是高效存储键值对的数据结构,更是展现设计艺术的典范。本文从基本概念、设计艺术和使用技巧三个方面,详细解析HashMap、TreeMap、LinkedHashMap等实现类,帮助您更好地理解和应用Java Map。
35 3
|
23天前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
26天前
|
机器学习/深度学习 调度
mmseg配置解析 Polynomial Decay 多项式衰减
Polynomial Decay(多项式衰减)是一种常用的学习率调度方法,通过多项式函数逐步减少学习率,帮助模型更好地收敛。公式为:\[ lr = (lr_{initial} - \eta_{min}) \times \left(1 - \frac{current\_iter}{max\_iters}\right)^{power} + \eta_{min} \]。参数包括初始学习率、最小学习率、当前迭代次数、总迭代次数和衰减指数。适用于需要平滑降低学习率的场景,特别在训练后期微调模型参数。
48 0
mmseg配置解析 Polynomial Decay 多项式衰减
|
22天前
|
JSON JavaScript 前端开发
深入解析ESLint配置:从入门到精通的全方位指南,精细调优你的代码质量保障工具
深入解析ESLint配置:从入门到精通的全方位指南,精细调优你的代码质量保障工具
63 0
|
26天前
|
监控 Java Maven
springboot学习二:springboot 初创建 web 项目、修改banner、热部署插件、切换运行环境、springboot参数配置,打包项目并测试成功
这篇文章介绍了如何快速创建Spring Boot项目,包括项目的初始化、结构、打包部署、修改启动Banner、热部署、环境切换和参数配置等基础操作。
106 0

推荐镜像

更多