SpringBoot自动装配的原理
SPI
原理
SPI (Service Provider Interface) 是Java提供的一种服务发现机制。通过SPI,框架可以动态加载和扩展具体的实现类,而不需要在代码中硬编码实现。SPI通常基于META-INF/services目录中的配置文件,框架会扫描并加载这些配置文件中声明的服务实现。
与API的区别
一般模块之间都是通过接口进行通讯,因此我们在服务调用方和服务实现方(也称服务提供者)之间引入一个“接口”。
-
当实现方提供了接口和实现,我们可以通过调用实现方的接口从而拥有实现方给我们提供的能力,这就是 API。这种情况下,接口和实现都是放在实现方的包中。调用方通过接口调用实现方的功能,而不需要关心具体的实现细节。
-
当接口存在于调用方这边时,这就是 **SPI ** 。由接口调用方确定接口规则,然后由不同的厂商根据这个规则对这个接口进行实现,从而提供服务。
优点
SPI 将服务接口和具体的服务实现分离开来,将服务调用方和服务实现者解耦,能够提升程序的扩展性、可维护性。修改或者替换服务实现并不需要修改调用方。
SpringBoot自动装配
原理
Spring Boot的自动装配功能通过@EnableAutoConfiguration注解来实现,它允许Spring容器根据项目的依赖和配置自动配置应用所需的Bean。这种机制极大地减少了开发者手动配置Bean的工作量。
为何说自动装配使用SPI
Spring Boot在实现自动装配时,使用了一种类似于SPI的机制。具体来说,Spring Boot会通过spring.factories文件(通常位于META-INF/目录下)来声明需要加载的自动配置类。spring.factories文件中列出了所有的@Configuration类,这些类提供了条件性自动装配的Bean定义。
在运行时,Spring Boot会根据依赖情况和环境判断哪些配置类需要加载,并将这些类注入到Spring上下文中。这种通过配置文件声明服务实现的方式与Java SPI的服务加载机制非常相似。
总结来说,Spring Boot的自动装配机制运用了类似SPI的动态服务发现和加载的思想,通过spring.factories文件来完成具体配置类的加载,因此可以说它在某种程度上是基于SPI机制的。
在项目中引入spring-boot-starter-data-redis,为何就能直接使用redisTemplate?
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
starter依赖的作用
spring-boot-starter-data-redis 是 Spring Boot 的 “starter” 依赖,“starter” 依赖并不包含具体的实现代码,而是用于聚合多个真正的依赖。它的作用是简化项目的依赖管理,通过引入 starter,会自动添加所需的其他库。
例如,spring-boot-starter-data-redis 实际上会引入以下几个核心依赖:
• spring-data-redis: 这是 Spring Data Redis 的核心实现。
• jedis 或 lettuce-core: Redis 的客户端库,具体取决于默认的配置。
当你引入 spring-boot-starter-data-redis 后,真正的 Redis 相关代码和功能来自于这些依赖,而不是 starter 本身。
spring-boot-autoconfigure的作用
1. 自动配置(Auto-Configuration)实现:
这个模块包含大量的自动配置类,这些类根据条件(例如类路径中是否存在某个依赖库,或者配置文件中是否存在某个属性)自动为应用配置适当的 Spring 组件(如数据库连接池、消息队列、Web 框架等)。
2. 简化配置:
通常,使用 Spring 框架时,开发者需要手动编写许多配置类或 XML 文件来注册各种 Bean。而有了 spring-boot-autoconfigure,这些 Bean 会根据项目依赖和默认设置自动配置,大大减少了手动配置的工作量。
3. 动态 Bean 创建:
自动配置类通常使用一系列条件注解(如 @ConditionalOnClass、@ConditionalOnMissingBean 等),根据条件动态地创建和注入 Bean。如果项目中引入了某些依赖库(如 H2 数据库或 Redis),Spring Boot 会自动配置与这些库相关的 Bean。
4. 模块化配置:
spring-boot-autoconfigure 将不同的功能模块进行拆分,每个模块有对应的自动配置类。例如,Web 自动配置类、JPA 自动配置类、Redis 自动配置类等。每个模块的配置都是可插拔的,可以通过启用或禁用某个模块的自动配置。
5. 与 spring.factories 文件配合:
这个模块使用 META-INF/spring.factories 文件定义了自动配置类的列表。Spring Boot 在启动时通过 SPI 机制加载这些自动配置类,从而触发自动配置的执行。
小结
spring-boot-autoconfigure模块的spring.factories文件中里面有大量的默认自动装配类,而这些装配类有使用@ConditionalOnClass注解;spring-boot-starter-data-redis它引入了redisTemplate真正实现,所以在自动装配的时候让@ConditionalOn