Mushroom Notes Mushroom Notes
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档

kinoko

一位兴趣使然的热心码农
🍄首页
  • JavaSE

    • 基础篇
    • 数据结构
    • IO流
    • Stream流
    • 函数式接口
    • JUC
    • 反射
    • 网络编程
    • 设计模式
  • JavaEE

    • Servlet
    • JDBC
    • 会话技术
    • 过滤器监听器
    • 三层架构
  • JDK

    • 总览
  • JVM

    • 总览
  • 常用mate
  • CSS
  • JavaScript
  • rds 数据库

    • MySQL
    • MySQL 进阶
    • MySQL 库表规范
  • nosql 数据库

    • Redis
    • Redis 进阶
    • Redis 底层
    • MongoDB
  • Spring生态

    • Spring
    • Spring MVC
    • Spring boot
    • Spring Validation
  • Spring Cloud生态

    • Spring Cloud
    • 服务治理
    • 远程调用
    • 网关路由
    • 服务保护
    • 分布式事务
    • 消息中间件
  • 数据库

    • Mybatis
    • Mybatis Plus
    • Elasticsearch
    • Redisson
  • 通信

    • Netty
📚技术
  • 方案专题
  • 算法专题
  • BUG专题
  • 安装专题
  • 网安专题
  • 面试专题
  • 常用网站
  • 后端常用
  • 前端常用
  • 分类
  • 标签
  • 归档
  • Linux

  • Docker

  • Nginx

  • Maven

  • 文件存储

  • 压测

  • Git技巧

  • GitHub技巧

  • 知识碎片

    • Swagger
    • Markdown使用教程
    • npm常用命令
    • Lua脚本语言
    • npm packageJson属性详解
    • yaml语言教程
    • 如何写一个自己的Springboot Starter
      • 1.编写自动配置类
      • 2.配置组件扫描
      • 3.编写spring.factories文件
      • 4.编写additional-spring-configuration-metadata.json文件
      • 5.打包
      • 使用
    • 如何写一个Redis会话客户端
  • 技术
  • 知识碎片
kinoko
2024-01-31
目录

如何写一个自己的Springboot Starter

主要分为以下几步骤:

  1. 编写自动配置类
  2. 配置组件扫描(可选)
  3. 编写spring.factories文件
  4. 编写additional-spring-configuration-metadata.json文件(可选)
  5. 打包

以我自己写的cache-spring-boot-starter (opens new window)为例。
image.png

# 1.编写自动配置类

@ConfigurationProperties(prefix = "spring.redisson")
@Import(ComponentImportSelector.class)
@Configuration
public class RedissonAutoConfiguration {

    private String file;

    @Bean
    public RedissonClient redissonClient() throws IOException {
        if (file == null) {
            throw new RuntimeException("can not found spring.redisson.file config from yaml");
        }
        if (file.startsWith("classpath:")) {
            return Redisson.create(Config.fromYAML(getClass().getClassLoader().getResourceAsStream(file.substring("classpath:".length()))));
        }
        return Redisson.create(Config.fromYAML(new File(file)));
    }

    public void setFile(String file) {
        this.file = file;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
  • @Configuration:声明配置类
  • @ConfigurationProperties(prefix = "spring.redisson"):配置文件映射
  • @Import(ComponentImportSelector.class)加载组件扫描器

# 2.配置组件扫描

public class ComponentImportSelector implements ImportSelector {

    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        // 从spring.factory中获取组件
        List<String> names = SpringFactoriesLoader.loadFactoryNames(ComponentImportSelector.class, null);
        return names.toArray(new String[0]);
    }
}
1
2
3
4
5
6
7
8
9

# 3.编写spring.factories文件

将自动配置类加入springboot自动装配扫描文件META-INF/spring.factories中:

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.kinoko.config.RedissonAutoConfiguration

# Bean Import
cn.kinoko.config.ComponentImportSelector=\
cn.kinoko.aspect.CacheableAspect,\
cn.kinoko.aspect.CacheEvictAspect,\
cn.kinoko.aspect.CachePutAspect,\
cn.kinoko.aspect.DistributedLockAspect,\
cn.kinoko.aspect.RateLimiterAspect,\
cn.kinoko.service.impl.RedisServiceImpl
1
2
3
4
5
6
7
8
9
10
11
12
  • Auto Configure:将配置类加入springboot的自动配置的selector扫描列表中。
  • Bean Import:将自己的BeanDefine加入组件扫描

注意

springboot2.7开始已经不推荐使用META-INF/spring.factories文件了,在springboot3完全弃用META-INF/spring.factories来加载自动配置类,改为使用META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports。

文件中直接写类路径:

cn.kinoko.config.RedissonAutoConfiguration
1

# 4.编写additional-spring-configuration-metadata.json文件

如果想在yaml或者properties文件中配置有提示,则可以创建META-INF/additional-spring-configuration-metadata.json文件:

{
  "properties": [
    {
      "name": "spring.redisson.file",
      "type": "java.lang.String",
      "description": "config yaml path",
      "defaultValue": "classpath:redisson.yaml"
    },
    {
      "name": "spring.redisson.type-match",
      "type": "java.lang.Boolean",
      "description": "是否开启key类型自动匹配",
      "defaultValue": false
    },
    {
      "name": "spring.redisson.enable-prefix",
      "type": "java.lang.Boolean",
      "description": "是否开启key前缀",
      "defaultValue": false
    },
    {
      "name": "spring.redisson.bloom-filter",
      "type": "cn.kinoko.config.ConfigProperties$BloomFilterConfig",
      "description": "布隆过滤器配置"
    },
    {
      "name": "spring.redisson.bloom-filter.key",
      "type": "java.lang.String",
      "description": "bloomFilter key name",
      "defaultValue": "bloom-filter"
    },
    {
      "name": "spring.redisson.bloom-filter.enable",
      "type": "java.lang.Boolean",
      "description": "是否开启",
      "defaultValue": false
    },
    {
      "name": "spring.redisson.bloom-filter.tolerate-error",
      "type": "java.lang.Double",
      "description": "容错率",
      "defaultValue": 0.05
    }
  ]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

注意

这个文件的配置只能生效在@ConfigurationProperties标记的配置类上,并且需要写getset方法,支持lombok,如果存在嵌套层级配置的话需要写内部类,不能写在外面引用,会导致无法识别。

示例:

@Setter
@Getter
@ConfigurationProperties(prefix = "spring.redisson")
@Configuration
public class ConfigProperties {

    private String file;
    private boolean enablePrefix;
    private boolean typeMatch;
    private BloomFilterConfig bloomFilter;

    public ConfigProperties() {
        file = "classpath:redisson.yaml";
        enablePrefix = false;
        typeMatch = false;
        bloomFilter = new BloomFilterConfig();
    }

    @Getter
    @Setter
    public static class BloomFilterConfig {

        private String key;
        private boolean enable;
        private double tolerateError;

        public BloomFilterConfig() {
            key = "boolean-filter";
            enable = false;
            tolerateError = 0.05;
        }
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

效果:
image.png

提示

更多配置可以参考:配置元数据 (opens new window)

# 5.打包

image.png

# 使用

引入依赖

<dependency>
  <groupId>cn.kinoko</groupId>
  <artifactId>cache-spring-boot-starter</artifactId>
  <version>1.0-SNAPSHOT</version>
</dependency>
1
2
3
4
5

业务

@RestController
@RequestMapping("/demo")
public class DemoController {

    @Autowired
    private RedisService redisService;

    @DistributedLock
    @GetMapping("/test")
    public String test() {
        LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(10));
        redisService.set("test", "test");
        return "test";
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#spring
上次更新: 2024/02/22 22:50:02
yaml语言教程
如何写一个Redis会话客户端

← yaml语言教程 如何写一个Redis会话客户端→

最近更新
01
JVM 底层
09-13
02
JVM 理论
09-13
03
JVM 应用
09-13
更多文章>
Theme by Vdoing | Copyright © 2022-2024 kinoko | MIT License | 粤ICP备2024165634号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式