• 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:softcentos7>vagrant up

      启动完成后,虚拟机变成运行状态,如下所示:

       然后,进入虚拟机,使用命令:

    D:softcentos7>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监控

    下节再述。

  • 相关阅读:
    javascript专业八级测试答案整理
    HTML中的attribute和property
    Ajax的原理和应用
    jQuery提交form表单
    使用JavaScript和Canvas实现下雪动画效果
    JavaScript经典代码总结
    从HTML5移动应用现状谈发展趋势
    前端单元测试总结及测试工具介绍
    Web缓存基础:术语、HTTP报头和缓存策略
    为IIS Express添加MIME映射
  • 原文地址:https://www.cnblogs.com/wfdespace/p/13268018.html
Copyright © 2020-2023  润新知