中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

java中的jar包案例分析

發布時間:2021-11-16 13:51:35 來源:億速云 閱讀:146 作者:iii 欄目:大數據

這篇文章主要介紹“java中的jar包案例分析”,在日常操作中,相信很多人在java中的jar包案例分析問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”java中的jar包案例分析”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!


遇到槽點

開發實踐中,對于開發一個 jar 包,很多人都只是完成功能,只要功能使用沒問題,就算是完事了,但其實遠遠不夠。當用戶使用 jar 包的時候,可能會遇到以下這些問題:

  1. 文檔缺失,一個功能怎么用,往往需要花半天到一天的時候到處找負責人,一步步溝通,很浪費時間;

  2. 依賴沖突,我只是引用了一個用戶認證包,結果把它支持的 SpringMVC、Jersey 和 Struts2 全引進來了;

  3. 方法完全不知道參數名,一個有三個參數的接口,我得對著文檔才能知道它們分別是什么意思,沒有文檔就得找負責人溝通或者自己一個個猜了;

  4. 跟Spring整合很不友好,例如初始化配置強制要求文件全路徑;

因為經常會遇到這樣的槽點,我在寫公共組件包的時候會特別留心。

在這里我總結出了以下七點改進建議,如果你也要提供 jar 包給其他人使用,可以參考。提升自己,方便他人。

文檔

作為一個公共的 jar 包,很多項目可能會使用到,如果你沒有文檔,那么每次有人要用的時候就會找你各種詢問,這樣即浪費自己的時間也會浪費大家的時間。而且用的人越多,你會發現,他們問的永遠都是那幾個問題:這個怎么用?你支持多種實現方式,我要選擇哪一種?如何申請使用?

如果你有一份簡單文檔就可以解決絕大多數的問題。

一份合格的文檔應該包含如下內容:

  1. 一句話描述本模塊的功能

  2. 快速開始,展示如何最簡單地開始使用

  3. 注意事項及常見問題

  4. 負責人聯系方式

一定要及時更新文檔,如果有文檔中沒有說明的問題,用戶找我們解決,記得要將這個解決方法記錄在常見問題中,為以后使用的人做參考。

其實一份文檔,說到底是為自己減輕工作量。試想,如果天天有人因為一些“雞毛蒜皮”的小事來各種問你,你又不得不花很多時間去溝通,有時溝通不好還會傷和氣。提供一份文檔,大家就都省事了。

最小依賴

如無必要,勿引依賴。若有必要引入,但是并非必須,記得使用 provided

例如,我們的 jar 包提供了快速整合 Spring 的功能,為此,我們需要添加 Spring 相關依賴,但是這個依賴是可選的,那么可以這樣設置:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
    <scope>provided</scope>
</dependency>

加上 provided 意味著打包的時候不會將這個依賴加入到 jar 包中,而是需要使用者自己引入

一個小小的設置,帶來的好處就是,如果這使用者不打算與 Spring 整合,那么他就不會間接地引入 Spring 的依賴了。這在一個大工程中相當重要,當一個項目中的外部依賴多了之后,外部依賴之間如果存在沖突,解決起來將會相當棘手。

附上源碼

不知道你有沒有過這樣的經歷:引用了一個 jar 包,準備開始使用的時候,代碼提示全是 var1, var2, var3 這種的,點進去一看,傻眼了:

java中的jar包案例分析

這時 IDEA 還親切地問你,要不要下載源碼(Download Sources)看一下?你滿心期待了點了 Download!結果:

java中的jar包案例分析

下載不了來問我要不要下載?玩我?

試想一下,這時你的用戶在用你的 jar 包的時候會不會也是這樣吐槽。那么怎么解決呢?

其實很簡單,只要在 pom 文件中添加 maven-source-plugin 插件即可

<!--配置生成源碼包-->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-source-plugin</artifactId>
    <version>3.0.1</version>
    <executions>
        <execution>
            <id>attach-sources</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

這樣就可以在編譯時添加源碼包,當發布到maven倉庫時,也會自動帶上源碼。用戶在使用 IDEA 的時候也就可以直接下載并關聯源碼了。因為關聯上源碼,你寫在上面的注釋也可以被使用者看見,這可比文檔好用得多哦

-parameters 參數

Java8 的反射中添加了 Parameter 類,讓我們能在程序運行期間通過反射獲取到方法參數信息,包括參數名。但是需要在程序編譯的時候添加 -parameters 參數。做為一個 jar 包,如果我們在編譯的時候沒有加這個參數,那么用戶將永遠無法通過反射獲取到參數名稱!這在某些場合下,可能會造成很大的不便。

其實,添加 -paramters 參數非常簡單,我們只需要在 pom 文件中添加 maven-compiler-plugin 插件,并且將 parameters 設置為 true 即可:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <source>${java.version}</source>
        <target>${java.version}</target>
        <parameters>true</parameters>
        <encoding>UTF-8</encoding>
    </configuration>
</plugin>

面向接口編程

做為一個公共 jar 包,我們是要對各個工程提供一個通用功能的,而這些功能一旦提供出去,需要保證兼容性,否則每次升級都將困難重重

因此,我們應該與使用者訂立“協議”,即通過接口訂立協議,宣告“我給大家提供這些能力,并且為之負責,你們無需關注我的底層實現,只需要按照協議使用即可”。在接口注釋中注明使用的場景和注意事項,因為我們前面添加了源碼包,因此使用者可以直接關聯并查看到我們寫下的注釋,例如:

java中的jar包案例分析

更極致的做法是我們只對接口負責我們可以隱藏實現類(將實現類設置為包級私有的),然后通過工廠方法提供接口的實現,而不是讓用戶自己 new。

這樣做之后,將來如果我們需要擴展,或者隨著技術的升級,我們需要更換底層實現時,無需擔心實現類中的兼容問題,只需要提供一個新的實現相同接口的實現類,讓工廠方法返回新的實現即可。而且舊的實現類,我們可以隨時刪除,減少歷史包袱

java中的jar包案例分析

包級私有的實現類:

java中的jar包案例分析

多種配置傳入方式

每個 jar 包基本都會有自己的一些配置,這些配置如果初始化,也是有很多講究。我遇到最不靠譜的做法就是要求必須提供文件的絕對路徑,甚至有些是只支持默認絕對路徑不支持自定義!

因為遇到很多這樣奇葩的包,因此在寫 jar 包的時候都會特別留意。

總結起來,我們應該提供如下三種配置的初始化方式:

  1. 文件路徑,必須支持 classpath: 前綴,代表從類路徑中加載

  2. InputStream,支持從流中讀取

  3. 自定義的 Config 類,包含所有需要用到的配置項,并設置默認值

其中第三種,自定義的 Config 類,是最推薦的做法。

以上面的客戶端為例,我們可以提供這樣三個構造器:

RocketMqEventClient(Config config) {
    this.config = config;
    client = new RocketMqClient();
}

RocketMqEventClient(InputStream in) {
    init(in);
}

RocketMqEventClient(String filePath) {
    if (filePath == null || filePath.trim().isEmpty()) {
        throw new IllegalArgumentException("文件路徑不能為空");
    }
    if (filePath.startsWith(CLASSPATH)) {
        // 從類路徑中加載
        String path = filePath.replaceFirst(CLASSPATH, "");
        try (InputStream in = RocketMqEventClient.class.getClassLoader().getResourceAsStream(path)) {
            init(in);
        } catch (IOException e) {
            throw new IllegalArgumentException("配置文件讀取失敗: " + filePath, e);
        }
    } else {
        // 直接讀取文件路徑
        try (InputStream in = new FileInputStream(filePath)) {
            init(in);
        } catch (IOException e) {
            throw new IllegalArgumentException("配置文件讀取失敗: " + filePath, e);
        }
    }
}

private void init(InputStream in) {
    config = new Config(in);
    client = new RocketMqClient();
}

然后在工廠類中支持這幾種參數類型:

/**
 * 事件客戶端工廠
 *
 * @author huangxuyang
 * @since 2019-06-29
 */
public class EventClientFactory {
    /**
     * 創建默認的事件客戶端
     *
     * @param config 各個配置項
     * @return 默認的事件客戶端
     */
    public static EventClient createClient(Config config) {
        return new RocketMqEventClient(config);
    }

    /**
     * 創建默認的事件客戶端
     *
     * @param in 配置文件輸入流
     * @return 默認的事件客戶端
     */
    public static EventClient createClient(InputStream in) {
        return new RocketMqEventClient(in);
    }

    /**
     * 創建默認的事件客戶端
     *
     * @param filePath 配置文件路徑,支持 classpath: 前綴
     * @return 默認的事件客戶端
     */
    public static EventClient createClient(String filePath) {
        return new RocketMqEventClient(filePath);
    }
}

支持 Spring @Enable 模式

隨著 SpringBoot 越來越流行,starter 這種配置方式讓我們感受到原來整合第三方依賴可以這么方便。如果我們的 jar 包也支持 starter 肯定很酷。但是我一般會考慮到很多項目不是使用 SpringBoot 構建,而是傳統的 Spring 項目,為了兼顧這些項目,其實我們可以采用 @EnableXxx 的模式,它與 starter 之間只是多了一個注解。我們只需要這么做:

  1. 引入 spring-context 依賴,注意加上 provided

  2. 在我們自定義的 Config 類的字段上使用 @Value 注解,自動從 Spring 上下文注入配置項

  3. 增加 XxxConfiguration 類,注冊 Bean

  4. 增加 @EnableXxx 注解,并導入剛剛定義的配置類 @Import({Config.class, XxxConfiguration.class})

以前面的事件客戶端為例,可以這樣做:

  1. 引入 spring-context

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.1.8.RELEASE</version>
    <scope>provided</scope>
</dependency>
  1. 為 Config 配置類的字段添加 @Value 注解

@lombok.Data
public class Config {
    @Value("${event.mq.namesrvaddr}")
    private String rocketMqNameSrvAddr;
    @Value("${event.mq.clientName}")
    private String rocketMqClientName;
    @Value("${event.mq.subject}")
    private String subject;
    @Value("${event.mq.pool.maxSize}")
    private int maxPoolSize;
}
  1. 添加 EventClientConfiguration 類

/**
 * 事件客戶端自動裝配配置類
 *
 * @author dadiyang
 * @since 2019-06-29
 */
@Configuration
public class EventClientConfiguration {
    @Bean
    public EventClient eventClient(Config config) {
        return EventClientFactory.createClient(config);
    }
}
  1. 添加 @EnableEventClient 注解

 /**
  * 啟用事件客戶端模塊
  *
  * @author dadiyang
  * @since 2019-06-29
  */
 @Documented
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Import({Config.class, EventClientConfiguration.class})
 public @interface EnableEventClient {
 }

有了這個注解之后,使用者如果與 Spring 整合的話,只需要在帶有 @Configuration 注解的類上標注 @EnableEventClient,然后就可以 @Autowired 自動注入我們的 EventClient 類了!

如果團隊全部都使用 SpringBoot 進行開發,也可以提供一個 starter。

到此,關于“java中的jar包案例分析”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

绥化市| 福建省| 屏山县| 淳安县| 迁安市| 安顺市| 东平县| 宣武区| 马山县| 石景山区| 手游| 连平县| 安顺市| 屏东市| 无为县| 江川县| 江城| 城步| 永顺县| 巴塘县| 乡城县| 资阳市| 三穗县| 修文县| 弥勒县| 全州县| 宁陵县| 玉环县| 东乌珠穆沁旗| 乐亭县| 商南县| 汝南县| 石家庄市| 盖州市| 兴仁县| 建宁县| 甘泉县| 江阴市| 榆林市| 保定市| 沈丘县|