引入
我们都知道SpringBoot的核心就是自动装配原理,对于自动装配的原理进行分析之后,我们可以基于这个机制来实现一个Starter组件,以便加深大家对自动装配及Starter组件的理解。同时,Spring Boot官方提供的Starter并不能囊括所有的技术组件,在工作中,如果自己的项目需要支持Spring Boot,也需要开发Starter组件。
概述
从Spring Boot官方提供的Starter的作用来看,Starter组件主要有三个功能:
(1)涉及相关组件的Jar包依赖;
(2)自动实现Bean的装配;
(3)自动声明并且加载application.properties文件中的属性配置。
规范
Starter的命名规范
Starter的命名主要分为两类,一类是官方命名,另一类是自定义组件命名。这种命名格式并不是强制性的,也是一种约定俗成的方式,可以让开发者更容易识别。
(1)官方命名的格式为:spring-boot-starter-模块名称,比如spring-boot-starter-web;
(2)自定义命名格式为:模块名称-spring-boot-starter,比如mybatis-spring-boot-starter。
简单来说,官方命名中模块名放在最后,而自定义组件中模块名放在最前面。
实例
虽然Spring Boot官方提供了spring-boot-starter-data-redis 组件来实现 RedisTemplate 的自动装配,但是在这里就着为了演示目的去如何实现一个基于Redis简化版本的Starter组件。
步骤
(1)创建一个工程,命名为redis-spring-boot-starter。
(2)添加Jar包依赖。
说明:Redisson提供了在Java中操作Redis的功能,并且基于Redis的特性封装了很多可直接使用的场景,比如分布式锁。
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.11.1</version>
</dependency>
(3)定义属性类,实现在application.properties中配置Redis的连接参数。
说明:由于只是一个简单版本的Demo,所以只简单定义了一些必要参数。另外@ConfigurationProperties这个注解的作用是把当前类中的属性和配置文件( properties/yaml )中的配置进行绑定,并且前缀是banq.redisson。
@ConfigurationProperties(prefix ="banq.redisson")
public class RedissonProperties {
private String host = "localhost";
private String password;
private int port = 6379;
private int timeout;
private boolean ssl;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getTimeout() {
return timeout;
}
public void setTimeout(int timeout) {
this.timeout = timeout;
}
public boolean isSsl() {
return ssl;
}
public void setSsl(boolean ssl) {
this.ssl = ssl;
}
}
(4)定义需要自动装配的配置类,主要就是把RedissonClient装配到IoC容器。
说明:@ConditionalOnClass,它表示一个条件,在当前场景中表示的是∶在classpath下存在Redisson这个类的时候,RedissonAutoConfiguration才会实现自动装配。另外,这里只演示了一种单机的配置模式,除此之外,Redisson还支持集群、主从、哨兵等模式的配置,大家有兴趣的话可以基于当前案例去扩展,建议使用config.fromYAML方式,直接加载配置完成不同模式的初始化,这会比根据不同模式的判断来实现配置化的方式更加简单。
@Configuration
@ConditionalOnClass(Redisson.class)
@EnableConfigurationProperties(RedissonProperties.class)
public class RedissonAutoConfiguration {
@Bean
RedissonClient redissonClient(RedissonProperties redissonProperties){
Config config = new Config();
String prefix = "redis://";
if (redissonProperties.isSsl()) {
prefix = "rediss://";
}
SingleServerConfig singleServerConfig = config.useSingleServer()
.setAddress(prefix + redissonProperties.getHost() + ":" + redissonProperties.getPort())
.setConnectTimeout(redissonProperties.getTimeout());
if (!StringUtil.isEmpty(redissonProperties.getPassword())) {
singleServerConfig.setPassword(redissonProperties.getPassword());
}
return Redisson.create(config);
}
}
(5)在resources下创建META-INF/spring.factories文件。
说明:使得Spring Boot程序可以扫描到该文件完成自动装配。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=ink.banq.RedissonAutoConfiguration
(6)使用Maven的install命令把项目打包成jar。
(7)在项目中使用:
添加Starter依赖
<dependency>
<groupId>ink.banq</groupId>
<artifactId>redis-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
设置属性配置
说明:在application.properties中配置host和port,这个属性会自动绑定到RedissonProperties中定义的属性上。
banq.redission.host = IP地址
banq.redission.port = 端口号
至此,一个非常简易的自定义Starter就完成了。