SpringBoot自定义starter

  • 距离上一篇文章,已经有一个月的时间了,近一段时间比较忙,也可能是比较懒得原因(哈哈哈哈哈),一直没有写博客。接下来算是出一篇博文吧。朋友经常鼓励我说,既然写了,就一定坚持下去,一定会有收获。感谢朋友们,同时也感谢大家的支持。
  • 碰见一个新的技术点,总会想起一句话:"这个技术是什么?为什么会出现?怎么用?",在面对一个新的技术时是不是有同样的疑问。走过这三点,技术的基本使用也就没有问题了。
  • 接下来一段时间,会写设计模式的文章来和大家做分享。

starter是什么?

  • Spring Boot Starter是SpringBoot开发出的一系列启动器,在应用启动时,被加载,可以很快速的处理应用所需要的的一些基础环境配置。SpringBoot的这种加载配置方式是一种SPI(Service Provider Interface)的方式,SPI可以在META-INF/service配置接口扩展的实现类,springBoot中原理类似,在SpringBoot启动时会默认加载扫描本项目下所有带@Configuration注解的类加载到应用程序中交给Spring容器进行管理。通常在spring.factories文件中以org.springframework.boot.autoconfigure.EnableAutoConfiguration=xxx.xxx.xxx键值对的方式来配置。该文件位于META-INF/spring.factories。

starter为什么会出现?

  • starter相当于一个集合,它把我们所需要的其他功能组件包裹起来,放到自己的pom文件中,当我们引用该starter时,其它功能组件也会引入进来。省去复杂的配置,力图做到使用最简单。可以将工具类定义成starter,上传到内网私服,可以使同事直接引用坐标即可。例如我们经常使用的spring-boot-starter-web、spring-boot-starter-data-jpa、spring-boot-starter-data-redis等等。

怎么自定义一个starter

  • 自定义一个starter也相当简单哦。遵循一定规则即可。
  1. starter的命名(不是强制),一般以xxx-spring-boot-starter。
  2. 自动配置类,用来初始化相关的Bean。
  3. 指明自动配置类的配置文件spring.factories。
  4. 自定义属性实体类,声明starter的应用配置属性。
  • 下面我们开始吧
  • 该工程命名为redis-spring-boot-starter(虽然名称为redis-spring-boot-starter,是模仿redis来编写此次代码的。有相关描述redis相关的具体代码SpringBoot封装单机和集群版Redis客户端),工程目录如下图:
  • pom依赖
    <?xml version="1.0" encoding="UTF-8"?>
    
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
      <modelVersion>4.0.0</modelVersion>
    
      <groupId>com.lee</groupId>
      <artifactId>redis-spring-boot-starter</artifactId>
      <version>1.0-SNAPSHOT</version>
    
      <name>redis-spring-boot-starter</name>
      <!-- FIXME change it to the project's website -->
      <url>http://www.example.com</url>
    
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
      </parent>
    
      <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.7</maven.compiler.source>
        <maven.compiler.target>1.7</maven.compiler.target>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.11</version>
          <scope>test</scope>
        </dependency>
    
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>
    
        <!--  配置文件显示-->
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-configuration-processor</artifactId>
        </dependency>
      </dependencies>
    
      <build>
        <pluginManagement>
          <plugins>
            <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>2.3.1</version>
              <configuration>
                <source>1.8</source>
                <target>1.8</target>
                <encoding>utf-8</encoding>
              </configuration>
            </plugin>
            <plugin>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-maven-plugin</artifactId>
              <version>2.2.5.RELEASE</version>
            </plugin>
          </plugins>
        </pluginManagement>
      </build>
    </project>
  • 定义一个映射配置文件的类
    @ConfigurationProperties(prefix="ext")会以ext开头去配置文件中读取对应的信息映射到实体类对应的属性上面。它不但能映射基本类型变量,也可以映射为Map和List等数据结构。
    package com.lee.properties;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    /**
     * @author zfl_a
     * @Desc 配置文件映射信息
     * @date 2020/8/7
     * @project redis-spring-boot-stater
     */
    @ConfigurationProperties(prefix = "ext")
    public class ExtProperties {
    
        private String msg ;
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    }
  • 定义一个Service
    package com.lee.service;
    
    import com.lee.properties.ExtProperties;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.AutoConfigureOrder;
    
    /**
     * @author zfl_a
     * @date 2020/8/7
     * @project redis-spring-boot-stater
     */
    public class ExtService {
    
        @Autowired
        private ExtProperties extProperties ;
    
        public String getExtInfo(){
    
            return extProperties.getMsg();
        }
    }
  • 定义一个配置类
  1. @Configuration,springBoot默认启动时会自动扫描该配置进行装配。
  2. @EnableConfigurationProperties({ExtProperties.class}) 注解。该注解是用来支持@ConfigurationProperties注解配置Bean的支持。
  3. @ConditionalOnMissingBean(ExtService.class) 交给Spring容器进行管理,缺失ExtService实例时该配置生效,可自定义扩展该配置。
    package com.lee.config;
    
    import com.lee.properties.ExtProperties;
    import com.lee.service.ExtService;
    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @author zfl_a
     * @date 2020/8/7
     * @project redis-spring-boot-stater
     */
    @Configuration
    @EnableConfigurationProperties({ExtProperties.class})
    public class ExtAutoConfiguration {
    
        /**
         * 交给Spring容器进行管理,缺失ExtService实例时该配置生效
         * @return
         */
        @Bean
        @ConditionalOnMissingBean(ExtService.class)
        public ExtService extService(){
            return new ExtService();
        }
    }
  • 在resources下新建META-INF文件夹,然后创建spring.factories文件,如下图:

该文件信息如下

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
      com.lee.config.ExtAutoConfiguration

测试

  1. 新建一个SpringBoot工程,将上面自定义的starter工程 mvn clean install到本地仓库,在新建的SpringBoot工程中引入该starter坐标。编写测试类测试即可。
  • 工程自行创建
  • 引入starter依赖
    <dependency>
          <groupId>com.lee</groupId>
          <artifactId>redis-spring-boot-starter</artifactId>
          <version>1.0-SNAPSHOT</version>
    </dependency>
  • 配置文件
    ext:
      msg: 自定义SpringBoot Starter
    server:
      port: 8088
  • 创建测试类
    package org.example.controller;
    
    import com.lee.service.ExtService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author zfl_a
     * @date 2020/8/7
     * @project test-spring-boot-starter
     */
    @RestController
    public class TestController {
    
        @Autowired
        private ExtService extService ;
    
        @GetMapping
        public String getExtInfo(){
            return extService.getExtInfo();
        }
    }
  • 访问结果如下图所示:

项目连接:https://gitee.com/enthusiasts/redis-spring-boot-starter

非常乐于和大家一起成长,如有纠正的地方,欢迎大家提出建议。
欢迎加群进行技术讨论,QQ群号:735259832 。
也可加本人微信wx_lee_hover_0212,欢迎交流学习(包括前端、后端、Linux运维)。
充满鲜花的世界到底在哪里
原文地址:https://www.cnblogs.com/aliases/p/13455638.html