springboot04_手写实现starter实现

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中引入相关依赖包
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>  //需要springboot的相关注解
      <version>2.3.1.RELEASE</version>
      <optional>true</optional>
    </dependency>
    <dependency>
      <groupId>org.redisson</groupId>  //作为redis客户端组件
      <artifactId>redisson</artifactId>
      <version>3.13.1</version>
    </dependency>

 

【2】创建redisson配置类

  主要实现RedissonClient这个bean实现条件装配。

  这个client类是用来连接redis服务器的。代码如下:

package com.wf.redission;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.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 class RedissonAutoConfiguration {
    //这里传参RedissonProperties实例,是要求这个bean自动装配到spring中的。如果未注入,是会报错的。
    //这里通过@EnableConfigurationProperties(RedissonProperties.class)配置类自动装配
    @Bean
    public RedissonClient redissonClient(RedissonProperties redissonProperties){
        Config config = new Config();
        String prefix = "redis://";
        //是否加密判断

        if(redissonProperties.isSsl()){
            prefix = "rediss://";
        }
        String address = prefix + redissonProperties.getHost()+":" + redissonProperties.getPort();
        SingleServerConfig singleServerConfig = config.useSingleServer().setAddress(address)
                    .setConnectTimeout(redissonProperties.getTimeout());
        return Redisson.create(config);
    }
}

 

  在这种远程连接的工具类,经常涉及到一个连接参数配置。可以在springboot的外部配置文件中

进行自行配置,这是如何实现的呢?

  实际上,是依赖注入一个外部文件配置类。

【3】外部文件配置类创建
package com.wf.redission;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
 * @ClassName RedissonProperties
 * @Description 配置文件类
 * @Author wf
 * @Date 2020/7/8 13:57
 * @Version 1.0
 */
@ConfigurationProperties(prefix = "wf.redisson")
public class RedissonProperties {
    private String host = "localhost";
    private int port = 6379;
    private int timeout;//超时时间
    private boolean ssl;//是否加密传输

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    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;
    }
}

 

说明:

  这里其实是@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依赖
<!--引入 自定义redission starter组件-->
        <dependency>
            <groupId>com.wf.redission</groupId>
            <artifactId>redission-spring-boot-starter</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>

 

【2】创建redisTestController
package com.wf.demo.springbootdemo.web;

import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @ClassName RedisTestController
 * @Description redis使用
 * @Author wf
 * @Date 2020/7/8 14:34
 * @Version 1.0
 */
@RestController
public class RedisTestController {
    @Autowired
    private RedissonClient redissonClient;

    @GetMapping("set")
    public String set(){
        RBucket<Object> bucket = redissonClient.getBucket("name");
        if(bucket.get() == null){
            bucket.set("wf.com");
        }
        return bucket.get().toString();
    }

}

 

【3】配置连接参数

 

 具体配置内容如下所示:

wf.redisson.host=127.0.0.1
wf.redisson.port=6379
wf.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组件中引入依赖包

 <!--外部配置提示功能-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-configuration-processor</artifactId>
      <version>2.3.1.RELEASE</version>
    </dependency>

 


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监控

下节再述。

 

posted @ 2020-07-08 17:06  我爱钻研  阅读(1290)  评论(2编辑  收藏  举报