springboot打jar包供第三方使用(以回调为例)

前言:

有时我们需要封装功能类库供第三方使用,这时候打包和我们平时发布项目有所不同。假设我们现在要对外提供一个计算功能,使用者只需要传入计算参数就能实现结果异步返回。最后还得对jar包进行混淆

1.编写回调函数类

我们先抽像出回调函数接口:
在这里插入图片描述
再新建一计算器类,含有加法和乘法:

在这里插入图片描述
一年级学生算加法:
在这里插入图片描述
二年级学生算乘法:
在这里插入图片描述
调用结果:
在这里插入图片描述
一般回调都是异步,比如说一年级学生在调用加法后要吃棒棒糖,二年级学生调用后要吃冰淇淋,而计算需要时间,不能让祖国的花朵在那傻等不是。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
最终代码如下:

回调接口

/**
 * 回调接口--在不确定使用者的情况下,建立一使用标准,实现该标准的都能使用此标准的回调函数
 */
public interface Norm {
    
    

   /**
    * 回调函数,接收反馈--通俗点来讲,就是你委托某人帮你办事(此例是委托计算器进行计算),他办完后通知你的渠道。
    * 此回调函数的r参数就是被委托人完事后(你调用的函数结束)返回的处理结果
    */
   void feedBack(int r);
}

计算器类

/**
 * 计算器类
 */
public class Calculator {
    
    


    /**
     * 加法计算
     * @param a 参数一
     * @param b 参数二
     * @param norm 使用者
     */
    public void add(int a, int b, Norm  norm) throws InterruptedException {
    
    
        System.out.println(Thread.currentThread().getName()+"加法需要3秒");
        Thread.sleep(3000);
        System.out.println(Thread.currentThread().getName()+"加法完成,通知委托人");
        norm.feedBack(a+b);
    }


    /**
     * 乘法计算
     * @param a 参数一
     * @param b 参数二
     * @param norm 使用者
     */
    public void sub(int a, int b, Norm  norm) throws InterruptedException {
    
    
        System.out.println(Thread.currentThread().getName()+"乘法需要4秒");
        Thread.sleep(4000);
        System.out.println(Thread.currentThread().getName()+"乘法完成,通知委托人");
        norm.feedBack(a*b);
    }


    public static void main(String[] args) throws InterruptedException {
    
    
        First first = new First();
        first.add(9,8);
        Second second = new Second();
        second.sub(9,8);
    }

一年级学生

/**
 * 一年级学生
 */
public class First implements Norm{
    
    

    @Override
    public void feedBack(int r) {
    
    
        System.out.println(Thread.currentThread().getName()+"一年级学生通过回调函数获取计算结果:"+r);
    }


    public void add(int a,int b) {
    
    
        System.out.println(Thread.currentThread().getName()+"一年级使用计算器算加法:"+a+"+"+b+"=");
        new Thread(()->{
    
    
            try {
    
    
                Thread.currentThread().setName("一年级子线程");
                new Calculator().add(a,b,this);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        ).start();
        System.out.println(Thread.currentThread().getName()+"一年级学生吃棒棒糖");
    }
}

二年级学生

/**
 * 二年级学生
 */
public class Second implements Norm{
    
    

    @Override
    public void feedBack(int r) {
    
    
        System.out.println(Thread.currentThread().getName()+"二年级学生通过回调函数获取计算结果:"+r);
    }


    public void sub(int a,int b){
    
    
        System.out.println(Thread.currentThread().getName()+"二年级使用计算器算乘法:"+a+"*"+b+"=");
        new Thread(()->{
    
    
            try {
    
    
                Thread.currentThread().setName("二年级子线程");
                new Calculator().sub(a,b,this);
            } catch (InterruptedException e) {
    
    
                e.printStackTrace();
            }
        }
        ).start();
        System.out.println(Thread.currentThread().getName()+"二年级学生吃冰淇淋");

    }
}

2.直接打JAR包(使用者必须手动)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3.加上组件扫描后打包

在这里插入图片描述
打包过程不再赘述
在这里插入图片描述
组件已注册,使用的时候只要扫描工具包所在包路径即可
在这里插入图片描述
包扫描可以去掉,同一路径默认会扫描
在这里插入图片描述

在这里插入图片描述
更改工具包的包路径
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

4.提供自定义注解

定义配置类,做为组件入口:

/**
 * 组件入口配置类,用来扫描所有组件
 */
@Configuration
@ComponentScan("com.stu.uitilsjar.**")
public class UtilsConfig {
    
    

 }

定义一个注解,用来导入配置类

@Retention(RetentionPolicy.RUNTIME)
@Target({
    
    ElementType.TYPE})
@Documented
@Import({
    
    UtilsConfig.class}) //此处是关键,导入组件入口配置类--使用者如果使用此注解,则导入配置类,配置类则扫描工具包下组件
public @interface EnableUtilsConfig {
    
    
}

现在我们换种打包方式,就像平常打包项目Jar包一样
在这里插入图片描述
生成的包如下
在这里插入图片描述
项目中再次重新导入jar包
在这里插入图片描述
在这里插入图片描述

5.使用spring.factories自动装配

在这里插入图片描述
重新打包后重新引入
在这里插入图片描述

6.混淆JAR包

根据情况配置插件

 <build>
        <finalName>${artifactId}</finalName>
        <plugins>
            <plugin>
                <groupId>com.github.wvengen</groupId>
                <artifactId>proguard-maven-plugin</artifactId>
                <executions>
                    <execution>
                        <phase>package</phase>
                        <goals><goal>proguard</goal></goals>
                    </execution>
                </executions>
                <configuration>
                    <proguardVersion>6.2.2</proguardVersion>
                    <injar>${project.build.finalName}.jar</injar>
                    <outjar>${project.build.finalName}.jar</outjar>
                    <!--<proguardInclude>${project.basedir}/proguard.cfg</proguardInclude>-->
                    <obfuscate>true</obfuscate>
                    <options>
                        <!-- 不做收缩(删除注释、未被引用代码)-->
                        <option>-dontshrink</option>
                        <!-- 不做优化(变更代码实现逻辑)-->
                        <option>-dontoptimize</option>
                        <!--保持目录结构,否则spring的自动注入无法使用-->
                        <option>-keepdirectories</option>
                        <option>-keepattributes Exceptions,InnerClasses,Signature,Deprecated,
                            SourceFile,LineNumberTable, *Annotation*,EnclosingMethod
                        </option>
                        <option>-adaptclassstrings</option>
                        <option>
                            <!-- 保护程序入口 -->
                            -keep class com.stu.uitilsjar.UitilsjarApplication { *; }
                        </option>
                        <option>-keepnames interface ** { *; }</option>
<!--                        &lt;!&ndash; 固定几个类不能混淆&ndash;&gt;-->
                        <option>-keep class com.stu.uitilsjar.callback.First { *; }</option>
                        <option>-keep class com.stu.uitilsjar.callback.Second { *; }</option>
                        <!-- 此选项将在所有包的所有类中保存所有原始定义的注释.-->
                        <option>
                            -keep class * {
                            @org.springframework.beans.factory.annotation.Autowired *;
                            @org.springframework.beans.factory.annotation.Value *;
                            @org.springframework.stereotype.Service *;
                            @org.springframework.stereotype.Component *;
                            @org.springframework.scheduling.annotation.Scheduled *;

                            }
                        </option>
                    </options>
                    <libs>
                        <!-- Include main JAVA library required.-->
                        <lib>${java.home}/lib/rt.jar</lib>
                        <lib>${java.home}/lib/jce.jar</lib>
                    </libs>
                </configuration>
                <dependencies>
                    <dependency>
                        <groupId>net.sf.proguard</groupId>
                        <artifactId>proguard-base</artifactId>
                        <version>6.2.2</version>
                    </dependency>
                </dependencies>
            </plugin>
        </plugins>
    </build>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/worilb/article/details/122517334