springboot jar package for third-party use (take callback as an example)

Foreword:

Sometimes we need to package functional class libraries for third-party use. At this time, packaging is different from our usual release projects. Suppose we now want to provide a calculation function to the outside world, and the user only needs to pass in the calculation parameters to realize the asynchronous return of the result. Finally, you have to confuse the jar package

1. Write a callback function class

Let's abstract the callback function interface first:
insert image description here
then create a new calculator class, including addition and multiplication:

insert image description here
First-grade students do addition:
insert image description here
second-grade students do multiplication:
insert image description here
Call result:
insert image description here
Generally, callbacks are asynchronous. For example, first-grade students want to eat lollipops after calling addition, and second-grade students want to eat ice cream after calling, and the calculation takes time. You can't let the flowers of the motherland wait there.
insert image description here
insert image description here
insert image description here
The final code is as follows:

callback interface

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

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

Calculator

/**
 * 计算器类
 */
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);
    }

First-year students

/**
 * 一年级学生
 */
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()+"一年级学生吃棒棒糖");
    }
}

sophomore

/**
 * 二年级学生
 */
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. Directly open the JAR package (the user must manually)

insert image description here
insert image description here
insert image description here

insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here
insert image description here

3. Add component scan and package

insert image description here
The packaging process will not be described in detail
insert image description here
. The component has been registered. When using it, just scan the package path where the toolkit is located.
insert image description here
Package scanning can be removed, and the same path will be scanned by default.
insert image description here

insert image description here
Change the package path of the toolkit
insert image description here

insert image description here

insert image description here

insert image description here

4. Provide custom annotations

Define the configuration class as the component entry:

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

 }

Define an annotation to import configuration classes

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

Now we change the packaging method, just like the usual packaging project Jar package. The
insert image description here
generated package is as follows.
insert image description here
Re-import the jar package again in the project
insert image description here
insert image description here

5. Automatic assembly using spring.factories

insert image description here
Reintroduced after repackaging
insert image description here

6. Confused JAR package

Configure the plugin according to the situation

 <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>

insert image description here
insert image description here
insert image description here
insert image description here

Guess you like

Origin blog.csdn.net/worilb/article/details/122517334
Recommended