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

简介: 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());  
  }  
}  


目录
相关文章
|
人工智能 Java 开发者
【Spring】原理解析:Spring Boot 自动配置
Spring Boot通过“约定优于配置”的设计理念,自动检测项目依赖并根据这些依赖自动装配相应的Bean,从而解放开发者从繁琐的配置工作中解脱出来,专注于业务逻辑实现。
3064 0
|
11月前
|
前端开发 Java 微服务
《深入理解Spring》:Spring、Spring MVC与Spring Boot的深度解析
Spring Framework是Java生态的基石,提供IoC、AOP等核心功能;Spring MVC基于其构建,实现Web层MVC架构;Spring Boot则通过自动配置和内嵌服务器,极大简化了开发与部署。三者层层演进,Spring Boot并非替代,而是对前者的高效封装与增强,适用于微服务与快速开发,而深入理解Spring Framework有助于更好驾驭整体技术栈。
|
11月前
|
XML JSON Java
【SpringBoot(三)】从请求到响应再到视图解析与模板引擎,本文带你领悟SpringBoot请求接收全流程!
Springboot专栏第三章,从请求的接收到视图解析,再到thymeleaf模板引擎的使用! 本文带你领悟SpringBoot请求接收到渲染的使用全流程!
694 3
|
12月前
|
Java 数据库 数据安全/隐私保护
Spring Boot四层架构深度解析
本文详解Spring Boot四层架构(Controller-Service-DAO-Database)的核心思想与实战应用,涵盖职责划分、代码结构、依赖注入、事务管理及常见问题解决方案,助力构建高内聚、低耦合的企业级应用。
1942 1
|
前端开发 Java 数据库连接
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
SpringBoot参数校验底层原理和实操。深度历险、深度解析(图解+秒懂+史上最全)
|
机器学习/深度学习 XML Java
【spring boot logback】日志logback格式解析
在 Spring Boot 中,Logback 是默认的日志框架,它支持灵活的日志格式配置。通过配置 logback.xml 文件,可以定义日志的输出格式、日志级别、日志文件路径等。
2090 5
|
Java 关系型数据库 数据库连接
Spring Boot项目集成MyBatis Plus操作PostgreSQL全解析
集成 Spring Boot、PostgreSQL 和 MyBatis Plus 的步骤与 MyBatis 类似,只不过在 MyBatis Plus 中提供了更多的便利功能,如自动生成 SQL、分页查询、Wrapper 查询等。
1149 2
|
Java 数据库连接 API
Java 对象模型现代化实践 基于 Spring Boot 与 MyBatis Plus 的实现方案深度解析
本文介绍了基于Spring Boot与MyBatis-Plus的Java对象模型现代化实践方案。采用Spring Boot 3.1.2作为基础框架,结合MyBatis-Plus 3.5.3.1进行数据访问层实现,使用Lombok简化PO对象,MapStruct处理对象转换。文章详细讲解了数据库设计、PO对象实现、DAO层构建、业务逻辑封装以及DTO/VO转换等核心环节,提供了一个完整的现代化Java对象模型实现案例。通过分层设计和对象转换,实现了业务逻辑与数据访问的解耦,提高了代码的可维护性和扩展性。
567 1
|
Java 数据库 开发者
Spring Boot 框架超级详细总结及长尾关键词应用解析
本文深入讲解Spring Boot框架的核心概念、功能特性及实际应用,涵盖自动配置、独立运行、starter依赖等优势。通过Web开发、微服务架构、批处理等适用场景分析,结合在线书店实战案例,演示项目初始化、数据库设计、分层架构实现全流程。同时探讨热部署、多环境配置、缓存机制与事务管理等高级特性,助你高效掌握Spring Boot开发技巧。代码示例详尽,适合从入门到进阶的学习者。
4405 0

热门文章

最新文章

推荐镜像

更多
  • DNS