当前位置: 首页 > article >正文

Spring/SpringBoot 的 自动装配与自动配置

1、概念理解

  • 自动装配(Auto - Wiring)

在 Spring 框架(包括 Spring Boot)中,自动装配是指 Spring 容器自动将一个 Bean(组件)注入到另一个 Bean 中。它主要用于解决 Bean 之间的依赖关系。

例如,假设有一个UserService类,它依赖于一个UserRepository类来进行数据库操作。在传统的配置方式下,需要在UserService的配置(如 XML 配置或者 Java 配置类)中显式地声明如何获取UserRepository的实例。而自动装配可以让 Spring 容器自动找到合适的UserRepository实例并注入到UserService中。

自动装配是通过@Autowired(在 Spring 中)或者@Resource等注解来实现的。@Autowired注解默认是按照类型(byType)进行装配,如果存在多个相同类型的 Bean,还可以结合@Qualifier注解按照名称(byName)进行更精确的装配。

  • 自动配置(Auto - Configuration) 

Spring Boot 自动配置是一种更高级的特性。它的目的是根据项目中添加的依赖(如数据库驱动、消息队列客户端等)和配置自动配置 Spring 应用程序的环境。

例如,当在pom.xml(如果是 Maven 项目)中添加了spring - boot - starter - web依赖,Spring Boot 会自动配置一个嵌入式的 Web 服务器(如 Tomcat),并且配置好相关的 Servlet、Filter 等 Web 组件的 Bean。

自动配置是基于一系列的条件判断和默认配置来实现的。Spring Boot 内部有很多自动配置类,这些类通过@Configuration注解标记,并且会使用@Conditional系列注解(如@ConditionalOnClass、@ConditionalOnMissingBean等)来判断是否需要进行特定的配置。比如,如果classpath下存在HikariCP相关的类,并且没有自定义的数据源配置,Spring Boot 可能会自动配置一个HikariCP数据源。

2、应用场景和目的 

  • 自动装配

主要用于处理 Bean 之间的依赖关系,让开发者能够更方便地构建复杂的对象图。它简化了对象之间的装配过程,减少了配置代码的数量。

例如,在一个大型的企业级应用中,可能有多个业务层服务(Service)和数据访问层(Repository)的 Bean,自动装配可以确保这些 Bean 之间的依赖正确地建立起来,提高代码的可维护性和可读性。

  • 自动配置 

用于快速搭建应用程序的运行环境。它使得开发者可以专注于业务逻辑的开发,而不需要花费大量时间在配置底层的框架和基础设施上。

例如,在开发一个微服务应用时,只要添加了相应的spring - boot - starter依赖,Spring Boot 就会自动配置好所需的大部分组件,如 Web 服务、数据库连接、缓存等,大大提高了开发效率。

3、实现机制 

3.1自动装配

Spring 容器在启动过程中,会解析带有自动装配注解(如@Autowired)的 Bean。它会通过反射机制查找符合条件的 Bean 来进行注入。具体来说,它首先会根据类型查找,如果找到多个相同类型的 Bean,会根据名称或者其他条件(如@Primary注解指定的首选 Bean)进一步筛选。这个过程涉及到 Spring 的 BeanFactory 和 ApplicationContext 的内部机制,它们维护了 Bean 的定义和实例的创建与管理。

3.2自动配置 

Spring Boot 的自动配置是基于@Configuration和@Conditional注解实现的。当 Spring Boot 应用启动时,它会扫描classpath下的自动配置类。这些自动配置类会根据各种条件(如类路径下是否存在特定的类、是否已经定义了某些 Bean 等)来决定是否要应用相应的配置。例如,DataSourceAutoConfiguration类会检查是否添加了数据库驱动依赖并且没有自定义数据源配置,如果满足条件,就会自动配置一个数据源。这个过程涉及到 Spring Boot 的自动配置加载机制,包括@EnableAutoConfiguration注解的作用以及SpringFactoriesLoader类在加载自动配置类中的角色。

3.2.1核心注解与启动机制 

  • Spring Boot 应用的入口通常是一个带有@SpringBootApplication注解的主类。这个注解是一个组合注解,它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan。

@Configuration:表明这个类是一个配置类,用于定义 Bean 和配置信息,相当于传统 Spring 中的 XML 配置文件的作用。例如,可以在这个配置类中使用@Bean注解定义一个 Bean,如定义一个自定义的数据源:

@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // 配置数据源的相关信息
        // 这里只是示例,实际可能会更复杂
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }
}

@ComponentScan:用于扫描指定包及其子包下的带有@Component、@Service、@Repository、@Controller等注解的组件,将它们注册为 Spring 容器中的 Bean。这样,Spring 就能自动发现和管理这些组件,例如,扫描一个com.example.service包下的所有服务类:

@ComponentScan("com.example.service")

@EnableAutoConfiguration:这是自动配置的关键注解。它实际上是借助@Import注解导入了AutoConfigurationImportSelector类。这个类会在 Spring Boot 应用启动时,从META - INF/spring.factories文件中加载自动配置类。

3.2.2自动配置类的加载

Spring Boot 会通过SpringFactoriesLoader类来加载META - INF/spring.factories文件中的自动配置信息。这个文件是一个键值对形式的配置文件,其中org.springframework.boot.autoconfigure.EnableAutoConfiguration是键,对应的值是一系列自动配置类的全路径名。
例如,当添加了spring - boot - starter - web依赖时,spring.factories文件中相关的自动配置类(如WebMvcAutoConfiguration)就会被加载。这些自动配置类会根据条件判断是否需要进行配置。

3.2.3条件判断机制

自动配置类中大量使用了@Conditional系列注解来决定是否应用配置。
@ConditionalOnClass:用于判断类路径下是否存在指定的类。例如,DataSourceAutoConfiguration类中可能会有这样的条件判断:

@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
    // 配置数据源相关的Bean
}

这意味着只有当类路径下存在DataSource类(通常是因为添加了数据库驱动依赖)时,这个自动配置类才会生效。
@ConditionalOnMissingBean:用于判断容器中是否已经存在指定类型的 Bean。如果不存在,才会进行相关 Bean 的配置。例如,在自动配置一个RestTemplate时,可能会有这样的条件:

@Configuration
@ConditionalOnMissingBean(RestTemplate.class)
public class RestTemplateAutoConfiguration {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

这表示如果容器中还没有RestTemplate这个 Bean,就会自动配置一个。通过这种条件判断机制,Spring Boot 可以根据项目的实际情况(如已经存在的 Bean 和类路径下的依赖)来灵活地进行自动配置,避免不必要的配置冲突和重复配置。

源自豆包~


http://www.kler.cn/a/487580.html

相关文章:

  • [免费]微信小程序(高校就业)招聘系统(Springboot后端+Vue管理端)【论文+源码+SQL脚本】
  • 这是什么操作?强制迁移?GitLab 停止中国区用户访问
  • 行情系统用什么数据库好
  • KCP解读:C#库类图
  • 【杂谈】-50+个生成式人工智能面试问题(一)
  • DuckDB:PRAGMA语句动态配置数据库行为
  • 如何操作github,gitee,gitcode三个git平台建立镜像仓库机制,这样便于维护项目只需要维护一个平台仓库地址的即可-优雅草央千澈
  • scala_【JVM】概述
  • Zabbix Api使用教程
  • 《零基础Go语言算法实战》【题目 1-16】字符串的遍历与比较
  • 微信小程序期末简答
  • vue+vite打包空白问题
  • Java 开发小技巧:使用 String.intern() 优化内存
  • antd-design-vue1.7.8浏览器中使用
  • P10424 [蓝桥杯 2024 省 B] 好数
  • 基于Springboot的景区民宿预约系统【附源码】
  • 理解Apache Spark中的宽窄依赖
  • LabVIEW瞬变电磁接收系统
  • Redis 优化秒杀(异步秒杀)
  • Debian source_list首次踩坑
  • 玩转 JMeter:Random Order Controller让测试“乱”出花样
  • WPF系列八:图形控件Path
  • GAN的应用
  • C语言Day14(c程序设计小红书+pta)
  • 物联网开发 的开发语言建议
  • 晨辉面试抽签和评分管理系统之五:面试准备时间倒计时管理