一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第10天,点击查看活动详情。
前言
我们想在要创建一个 Spring 项目有多简单?
- 使用 Spring Initializer 创建一个 SpringBoot 项目
- 得到一个 Application.java
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
运行 Application.java,项目就可以启动了,如果我们对默认的配置不满意,或者需要补充或覆盖默认的配置,我们直接在 application.properties 配置文件中就可以搞定。
为什么 SpringBoot 可以用起来这么酸爽呢?这一切都得益于 SpringBoot 的自动装配,本文就来探究一下 SpringBoot 的自动装配原理。
什么是自动装配?
事实上,自动装配并不是 SpringBoot 实现的,在 Spring 框架中早就有了这个功能,但 SpringBoot 在这基础上,通过 SPI 的方式,做了进一步的优化,让自动装配更好用。
Spring Boot 遵循约定大于配置的原则,定义了一套接口规范,这套规范规定:Spring Boot 在启动时会扫描外部引用 jar 包中的 META-INF/spring.factories 文件,将文件中配置的类型信息加载到 Spring 容器,并执行类中定义的各种操作。对于外部 jar 来说,只需要按照 Spring Boot 定义的标准,就能将自己的功能自动装配到 Spring Boot。
在 SpringBoot 中,如果我们要使用某些第三方依赖,我们直接在项目中引入 starter 即可,比如下面的例子。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
如果你的 Redis 部署在本地,你甚至不需要任何配置就能直接使用代码开始操控 Redis,而不需要进行任何配置。
自动装配流程
还是以 spring-boot-starter-data-redis 为例,我们来看一下 Spring Boot 是如何进行自动装配的。
1)引入依赖
首先我们会在一个项目中,引入某个版本的 spring-boot-starter-data-redis 的依赖,前提是它与我们的 Spring Boot 版本兼容,对于胡乱的版本引入,项目出现依赖冲突的概率接近必然。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.6.5-SNAPSHOT</version>
</dependency>
2)获取 Redis 相关配置类的全限定名
在 spring-boot-actoconfigure.jar/META-INF/spring.factories 中,有很多很多功能配置类的全限定名,一般一个功能配置类围绕该功能,负责管理创建多个相关的功能类,比如 org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 负责管理和创建 JedisConnectionFactor、RedisTemplate、StringRedisTemplate 这几个功能类的创建。
这里的重点是 @ConditionalOnClass 注解,这个声明意味着在 classpath 路径下如果存在 RedisOperations.class,那么 RedisAutoConfiguration 就是生效的。
我们在第一步的时候引入了 Redis 的 starter 依赖,这样 Spring Boot 的自动装配机制就能在 classpath 下找到 RedisOperations.class。
4)注入默认的属性配置类
当功能配置类生效的时候,会根据@EnableConfigurationProperties(RedisProperties.class) 声明,注入默认的属性配置类。
5)创建对应的类
Redis 功能配置里面会根据条件生成最终的 JedisConnectionFactory、RedisTemplate,并提供了默认的配置形式 @ConditionalOnMissingBean(name = "redisTemplate")。
在实际使用的时候,如果我们在配置文件中自定义了一些配置,比如 Redis 的地址、端口号等等,注解 @ConditionalOnMissingBean(name = "redisTemplate") 会让默认配置被覆盖,从而使用我们自定义的配置。
@Bean
@ConditionalOnMissingBean(name = "redisTemplate")
public RedisTemplate<Object, Object> redisTemplate(
RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
6)使用 RedisTemplate
至此,在启动的过程中,RedisTemplate 就已经被创建并配置好了,我们只需要在代码中注入就可以直接使用了,就像下面这样
@Autowired
private RedisTemplate redisTemplate;
写在后面
本文对 Spring Boot 的自动装配流程做了一个简要的分析,目的是让看官对 Spring Boot 的自动装配有一个清晰的了解,但本文远没有深入的原理的程度进行分析。
我的目的是让读者看阅读起来“不累”,哪怕是深入原理也不会一次写太多,这是我的写作风格,我相信每天积累一点点,菜鸟也可以变大神!
如果本文对你有帮助希望你能点个赞👍。