4.1.7.手写实现一个spring boot starter实现
时长:40min
4.1.springboot starter组件
4.1.1.springboot starter组件的实现原理
如果创建一个springboot项目,会在pom.xml自动添加一个starter组件。
4.1.1.1.stater组件的类型
starter包有官方定义包,和第三方定义包。
1.官方starter
命名格式:spring-boot-starter-xxx,如:spring-boot-starter-web
自动装配,是基于条件装配。
2.第三方starter
命名格式:xxx-spring-boot-starter,如:mybatis-spring-boot-starter
自动装配,是基于spring.factories配置文件装配
4.1.1.2.starter组件做了哪些事情?
starter组件,实际是定义一个模块。它所做的工作包括:
》整合相关依赖包
》完成自动装配
4.1.2.基于redis手写一个starter
4.1.2.1.开发准备
查看本机本地环境是否有安装redis服务端。个人通过virtualbox + vagrant安装centos7系统。
希望在centos上安装redis服务器程序。【这里是在windows系统下】
1.启动虚拟机
首先,运行virtualbox软件,刚开始虚拟机是关闭状态。
然后到centos安装目录,打开cmd,启动vagrant,使用命令:
D:\soft\centos7>vagrant up
启动完成后,虚拟机变成运行状态,如下所示:
然后,进入虚拟机,使用命令:
D:\soft\centos7>vagrant ssh
Last login: Mon Jan 6 08:43:36 2020 from 10.0.2.2
[vagrant@localhost ~]$ //这里是vagrant普通用户登录
查看ip,使用命令:ip a【这里可以当作是127.0.0.1】
然后,使用xshell工具连接服务端。
然后,查看是否有安装redis服务器,如果没有,先进行安装。
然后,启动redis,如下所示:
4.1.2.2.开发一个starter
1.创建一个maven工程,开发一个redission的starter组件
因为是自定义的第三方starter包,项目命名为:redission-spring-boot-starter
【1】pom.xml中引入相关依赖包
org.springframework.boot
spring-boot-starter //需要springboot的相关注解
2.3.1.RELEASE
true
org.redisson //作为redis客户端组件
redisson
3.13.1
【2】创建redisson配置类
主要实现RedissonClient这个bean实现条件装配。
这个client类是用来连接redis服务器的。代码如下:
packagecom.wf.redission;importorg.redisson.Redisson;importorg.redisson.api.RedissonClient;importorg.redisson.config.Config;importorg.redisson.config.SingleServerConfig;importorg.springframework.boot.autoconfigure.condition.ConditionalOnClass;importorg.springframework.boot.context.properties.EnableConfigurationProperties;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;/*** @ClassName RedissonAutoConfiguration
* @Description 配置类
* @Author wf
* @Date 2020/7/8 13:44
* @Version 1.0*/@Configuration
@ConditionalOnClass(Redisson.class)
@EnableConfigurationProperties(RedissonProperties.class)public classRedissonAutoConfiguration {//这里传参RedissonProperties实例,是要求这个bean自动装配到spring中的。如果未注入,是会报错的。//这里通过@EnableConfigurationProperties(RedissonProperties.class)配置类自动装配
@BeanpublicRedissonClient redissonClient(RedissonProperties redissonProperties){
Config config= newConfig();
String prefix= "redis://";//是否加密判断
if(redissonProperties.isSsl()){
prefix= "rediss://";
}
String address= prefix + redissonProperties.getHost()+":" +redissonProperties.getPort();
SingleServerConfig singleServerConfig=config.useSingleServer().setAddress(address)
.setConnectTimeout(redissonProperties.getTimeout());returnRedisson.create(config);
}
}
在这种远程连接的工具类,经常涉及到一个连接参数配置。可以在springboot的外部配置文件中
进行自行配置,这是如何实现的呢?
实际上,是依赖注入一个外部文件配置类。
【3】外部文件配置类创建
packagecom.wf.redission;importorg.springframework.boot.context.properties.ConfigurationProperties;/*** @ClassName RedissonProperties
* @Description 配置文件类
* @Author wf
* @Date 2020/7/8 13:57
* @Version 1.0*/@ConfigurationProperties(prefix= "wf.redisson")public classRedissonProperties {private String host = "localhost";private int port = 6379;private int timeout;//超时时间
private boolean ssl;//是否加密传输
publicString getHost() {returnhost;
}public voidsetHost(String host) {this.host =host;
}public intgetPort() {returnport;
}public void setPort(intport) {this.port =port;
}public intgetTimeout() {returntimeout;
}public void setTimeout(inttimeout) {this.timeout =timeout;
}public booleanisSsl() {returnssl;
}public void setSsl(booleanssl) {this.ssl =ssl;
}
}
说明:
这里其实是@ConfigurationProperties(prefix = "wf.redisson")注解起重要作用。
【4】创建配置文件实现自动装配
创建resources资源文件夹,然后创建META-INF文件夹,并在该目录下创建spring.factories配置文件,
如下所示:
配置内容如下所示:
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wf.redission.RedissonAutoConfiguration
然后,这个组件就开发完成了。下面进行打包发布。
2.创建springboot项目,引入该starter,进行使用
【1】pom.xml中引入starter依赖
com.wf.redission
redission-spring-boot-starter
1.0-SNAPSHOT
【2】创建redisTestController
packagecom.wf.demo.springbootdemo.web;importorg.redisson.api.RBucket;importorg.redisson.api.RedissonClient;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RestController;/*** @ClassName RedisTestController
* @Description redis使用
* @Author wf
* @Date 2020/7/8 14:34
* @Version 1.0*/@RestControllerpublic classRedisTestController {
@AutowiredprivateRedissonClient redissonClient;
@GetMapping("set")publicString set(){
RBucket bucket = redissonClient.getBucket("name");if(bucket.get() == null){
bucket.set("wf.com");
}returnbucket.get().toString();
}
}
【3】配置连接参数
具体配置内容如下所示:
wf.redisson.host=127.0.0.1wf.redisson.port=6379wf.redissson.timeout=3000
【4】启动springboot项目,进行测试
启动失败,因为redis连接失败。如下所示:
连接失败的原因,可能是ip配置不对。
目前配置ip为127.0.0.1,需要查看虚拟机中ip地址是多少。
然后,配置成静态ip:192.168.33.10,再次启动失败。猜想是redis远程连接未设置好。
结果,果然是这样。所以,启动成功。访问接口如下:
说明:
redis远程连接,测试通过。说明starter定义成功。
3.开发问题总结
虽然我们的starter开发成功了,功能没有问题。但是,我在springboot进行配置连接参数时,
key是没有提示的。
如何能够实现这种提示功能呢?还是需要修改starter组件。
【1】开发外部配置key提示功能
A.starter组件中引入依赖包
org.springframework.boot
spring-boot-configuration-processor
2.3.1.RELEASE
B.META-INF下添加配置文件additional-spring-configuration-metadata.json
这个文件会配置属性解析,属性值。从而可以增加一些自动化的描述。
文件内容如何配置,可以参考springboot中的配置文件,如下所示:
{
"properties": [
{
"sourceType": "org.apache.ibatis.session.Configuration",
"defaultValue": "org.apache.ibatis.scripting.xmltags.XMLLanguageDriver",
"name": "mybatis.configuration.default-scripting-language",
"description": "A default LanguageDriver class.",
"type": "java.lang.Class<?extends org.apache.ibatis.scripting.LanguageDriver>",
"deprecation": {
"reason": "Because when this configuration property is used, there is case that custom language driver cannot be registered correctly.",
"replacement": "mybatis.default-scripting-language-driver"
}
},
{
"sourceType": "org.apache.ibatis.session.Configuration",
"defaultValue": "org.apache.ibatis.type.EnumTypeHandler",
"name": "mybatis.configuration.default-enum-type-handler",
"description": "A default TypeHandler class for Enum.",
"type": "java.lang.Class extends org.apache.ibatis.type.TypeHandler>"
},
{
"defaultValue": false,
"name": "mybatis.lazy-initialization",
"description": "Set whether enable lazy initialization for mapper bean.",
"type": "java.lang.Boolean"
},
{
"name": "mybatis.scripting-language-driver.velocity.userdirective",
"deprecation": {
"level": "error",
"reason": "The 'userdirective' is deprecated since Velocity 2.x. This property defined for keeping backward compatibility with older velocity version.",
"replacement": "mybatis.scripting-language-driver.velocity.velocity-settings.runtime.custom_directives"
}
}
]
}
当前组件的配置内容如下:
{
"properties":[{
"name": "wf.redisson.host",
"type": "java.lang.String",
"description": "redis的服务器地址",
"defaultValue": "localhost"
},
{
"name": "wf.redisson.port",
"type": "java.lang.Integer",
"description": "redis服务开放端口号",
"defaultValue": 6379
},
{
"name": "wf.redisson.timeout",
"type": "java.lang.Integer",
"description": "redis的服务器连接超时时间",
"defaultValue": 3000
},
{
"name": "wf.redisson.ssl",
"type": "java.lang.Boolean",
"description": "redis数据传输是否加密",
"defaultValue": false
}]}
开发就完成了,重新打包发布。
【2】回到springboot项目中测试
发现已经重新打包,还是不能提示。后面我找到原因。
配置的这个路径:wf.redisson必须与包路径定义一样,原来我的包路径定义为com.wf.redission
所以,不能解析成功。
现在我修改一致之后,重新打包starter项目,在jar包中会自动生成一个spring-configuration-metadata.json
文件,这个文件才是导致key配置提示的关键。生成文件如下所示:
下面回到springboot项目中,进行配置,验证是否会key提示。 可以发现,提示功能成功了。
4.2.Actuator监控
下节再述。