• 自己实现SpringBoot三方Starer依赖封装(自动装配自定义实现)


    一.对Spring Boot自动装配理解
    自动装配其实是一种按照SpringBoot的约定配置规则实现三方依赖注入项目,通过配置文件+注解实现配置文件识别以及对应的Bean等IOC注入,供SpringBoot 使用.
    具体自动装配原理可以参考下边博文学习
    https://www.cnblogs.com/monkey-xuan/p/15911610.html
    二.自己封装自定义Starter
    被封装项目创建Springboot项目或者maven项目
    创建自定义配置类

    package com.example.springstarerredisautoconfig.redisson;
    
    import org.redisson.Redisson;
    import org.redisson.api.RedissonClient;
    import org.redisson.config.Config;
    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;
    
    @ConditionalOnClass(Redisson.class)
    @EnableConfigurationProperties(RedissonProperties2.class)
    @Configuration
    public class RedissonAutoConfiguration {
    
        @Bean
        public RedissonClient redissonClient(RedissonProperties2 redissonProperties) {
            final Config config = new Config();
            String prefix = "redis://";
            if (redissonProperties.isSsl()) {
                prefix="rediss://";
            }
            String address = prefix+redissonProperties.getHost()+":"+redissonProperties.getPort();
            config.useSingleServer().setAddress(address);
    
            return Redisson.create(config);
        }
    }
    
    • 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

    RedissonProperties2

    package com.example.springstarerredisautoconfig.redisson;
    
    import org.springframework.boot.context.properties.ConfigurationProperties;
    
    @ConfigurationProperties(prefix = "bobo.redisson")
    public class RedissonProperties2 {
        private String host = "localhost";
        private Integer port = 6379;
        private int timeout = 1000;
        private boolean ssl = false;
    
        public String getHost() {
            return host;
        }
    
        public void setHost(String host) {
            this.host = host;
        }
    
        public Integer getPort() {
            return port;
        }
    
        public void setPort(Integer 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;
        }
    
        @Override
        public String toString() {
            return "RedissonProperties{" +
                    "host='" + host + '\'' +
                    ", port=" + port +
                    ", timeout=" + timeout +
                    ", ssl=" + ssl +
                    '}';
        }
    }
    
    • 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
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    resources文件下创建META-INF文件夹
    添加spring.factories文件 主要是通过它扫描配置文件是否注入IOC

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    com.example.springstarerredisautoconfig.redisson.RedissonAutoConfiguration
    
    • 1
    • 2

    此刻需要注意如果通过SpringBoot项目打包依赖jar需要SpringBoot可执行jar和可依赖jar前置只是,如果maven项目打包就直接是可依赖jar不存在该问题
    目前我的是SpringBoot打包依赖jar方式
    删除test文件夹,不然报错
    pom改变打包方式

            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-configuration-processor</artifactId>
            </dependency>
            <dependency>
                <groupId>org.redisson</groupId>
                <artifactId>redisson</artifactId>
                <version>3.16.1</version>
            </dependency>
    
            //修改打包方式
            <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                    <configuration>
                        <classifier>exec</classifier>
                    </configuration>
            </plugin>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    主工程

    引入打包依赖

            <dependency>
                <groupId>com.example</groupId>
                <artifactId>SpringStarerRedisAutoConfig</artifactId>
                <version>0.0.1-SNAPSHOT</version>
            </dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    示例代码

    package com.example.springbootstart5.controller;
    
    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;
    
    @RestController
    public class UserController {
    
        @Autowired
        private RedissonClient redissonClient;
    
        @GetMapping("/query")
        public String query(){
            int[] a = new int[4];
            final int length = a.length;
            String string = "a";
            final int length1 = string.length();
            return "key的" + redissonClient.getKeys().count() + "";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    配置文件属性

    bobo.redisson.host=172.16.131.140
    bobo.redisson.port=6379
    bobo.redisson.ssl=false
    bobo.redisson.timeout=1000
    
    • 1
    • 2
    • 3
    • 4

    项目启动后,被自定义的starter中redissonClient成功注入SpringBoot IOC.

    附加知识关于SpringBoot可执行jar和普通依赖jar区别

    1. 产生的问题

    Spring Boot 项目打包成的可运行 jar包 ,被其他项目依赖之后,总是报错找不到类的错误?

    这是由于还没有搞清楚可执行 jar 和普通 jar 到底有什么区别导致的。

    1. 可运行jar与普通jar的区别

    普通jar包:可以被其他项目应用依赖,不可以用 java -jar xxx.jar 运行。
    可运行jar包:不可以被其他项目应用依赖,可以用 java -jar xxx.jar 运行。
    注:SpringBoot项目默认打包的是可运行jar包,普通项目默认打包的是不可运行的jar包,但是,普通项目也可以打包成可运行jar包。

    疑问:

    同样是执行mvn package命令进行项目打包,为什么 Spring Boot 项目就打成了可执行 jar ,而普通项目则打包成了不可执行 jar 呢?

    解答:
    Spring Boot 项目默认的插件配置 spring-boot-maven-plugin 依赖包,这个打包插件存在 5 个方面的功能,如下:
    在这里插入图片描述
    在这里插入图片描述
    五个功能分别是:

    (1)build-info:生成项目的构建信息文件 build-info.properties
    (2)repackage:这个是默认 goal,在 mvn package 执行之后,这个命令再次打包生成可执行的 jar,同时将 mvn package 生成的 jar 重命名为 *.origin
    (3)run:这个可以用来运行 Spring Boot 应用
    (4)start:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理
    (5)stop:这个在 mvn integration-test 阶段,进行 Spring Boot 应用生命周期的管理

    默认情况下使用就是 repackage 功能,其他功能要使用,则需要开发者显式配置。

    1. 了解打包过程

    SpringBoot的repackage 功能的 作用,就是在打包的时候,多做一点额外的事情:

    (1)首先 mvn package 命令 对项目进行打包,打成一个 jar,这个 jar 就是一个普通的 jar,可以被其他项目依赖,但是不可以被执行
    (2)repackage 命令,对第一步 打包成的 jar 进行再次打包,将之打成一个 可执行 jar ,通过将第一步打成的 jar 重命名为 *.original 文件

    举例说明:

    Spring Boot 项目进行打包,可以执行 mvn package 命令,也可以直接在 IDEA 中点击 package进行打包,打包结果如下显示:

    在这里插入图片描述
    可以看到有两个文件,admin-0.0.1-SNAPSHOT.jar 是可运行jar包,admin-0.0.1-SNAPSHOT.jar.original是被重命名的 可依赖jar包。

    1. jar包之间的差异

    可执行 jar 包结构
    在这里插入图片描述
    可执行 jar 中,我们自己的代码是存在 于 BOOT-INF/classes/ 目录下,另外,还有一个 META-INF 的目录,该目录下有一个 MANIFEST.MF 文件,打开该文件,内容如下:

    Manifest-Version: 1.0
    Created-By: Maven Jar Plugin 3.2.0
    Build-Jdk-Spec: 14
    Implementation-Title: admin
    Implementation-Version: 0.0.1-SNAPSHOT
    Main-Class: org.springframework.boot.loader.JarLauncher
    Start-Class: org.yolo.admin.AdminApplication
    Spring-Boot-Version: 2.3.4.RELEASE
    Spring-Boot-Classes: BOOT-INF/classes/
    Spring-Boot-Lib: BOOT-INF/lib/
    Spring-Boot-Classpath-Index: BOOT-INF/classpath.idx
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Start-Class : 这就是可执行 jar 的入口类
    Spring-Boot-Classes : 代码编译后的位置
    Spring-Boot-Lib : 项目所依赖的 jar 的位置

    如果自己要打一个可执行 jar 包的话,除了添加相关依赖之外,还需要配置 META-INF/MANIFEST.MF 文件。

    不可执行 jar 包的结构:

    首先将默认的后缀 .original 除去,然后给文件重命名 .jar,重命名完成,进行解压 如下:
    在这里插入图片描述
    不可执行 jar 根目录就相当于我们的 classpath,直接就能看到我们的代码,并且也拥有 META-INF/MANIFEST.MF 文件,但是文件中没有定义启动类等配置。

    Manifest-Version: 1.0
    Created-By: Maven Jar Plugin 3.2.0
    Build-Jdk-Spec: 14
    Implementation-Title: admin
    Implementation-Version: 0.0.1-SNAPSHOT
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注:这个不可以执行 jar 也没有将项目的依赖打包进来。
    由此可见这两个jar包内部结构是完全不同的,因此一个可以直接执行,另一个则可以被其他项目依赖。

    1. 同时打包两个jar包

    提议:一般来说,Spring Boot 直接打包成可执行 jar 就可以了,不建议将 Spring Boot 作为普通的 jar 被其他的项目所依赖。如果有这种需求,建议将被依赖的部分,单独抽出来做一个普通的 Maven 项目,然后在 Spring Boot 中引用这个 Maven 项目。

    依环境必须实现可依赖jar的话,如下可以实现:

    pom.xml文件中spring-boot-maven-plugin 插件添加如下配置:

    <build>
      <plugins>
        <plugin>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-maven-plugin</artifactId>
          <configuration>
            <classifier>exec</classifier>
          </configuration>
        </plugin>
      </plugins>
    </build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    classifier : 表示可执行 jar 的名字 , 执行 repackage 命令时,就不会给 mvn package 所打成的 jar 重命名 , 如下:
    在这里插入图片描述
    第一个 jar 表示可以被其他项目依赖的 jar ,第二个 jar 则表示一个可执行 jar。

  • 相关阅读:
    上周热点回顾(6.3-6.9)
    作物检测:YOLOv8+SwanLab
    从effect理解Vue3的响应式原理
    element table中嵌套el-select 无法选择问题
    Docker搭建runcher教程
    Linux 驱动开发 五十六:《gpio.txt》翻译
    算法刷题笔记--二叉树篇
    java基于ssm的 大学生社团管理系统 elementui 前后端分离
    LeetCode - 547 省份数量
    如何解决NSIS 2G文件的限制
  • 原文地址:https://blog.csdn.net/m0_37135879/article/details/133212124