2017 年不容錯過的 10+ 個開源 Java 庫

liangshe093u 7年前發布 | 17K 次閱讀 Java 開源 Java開發

這些開源庫非常棒,我已經將它們整理成參考清單,附上簡短的功能清單連同案例一同分享。

Guice

Guice(音同“juice”)是谷歌開發的一個輕量級的依賴注入框架,支持 java 6 及以上版本。

# Typical dependency injection
public class DatabaseTransactionLogProvider implements Provider<TransactionLog> {
  @Inject Connection connection;

  public TransactionLog get() {
    return new DatabaseTransactionLog(connection);
  }
}
# FactoryModuleBuilder generates factory using your interface
public interface PaymentFactory {
   Payment create(Date startDate, Money amount);
 }

OkHttp

HTTP 是現代應用程序實現互聯的機制。數據和媒體的交互都基于此。高效的 http 機制能提升你的下載速度和節約帶寬。

OkHttp 作為一個HTTP客戶端,默認:

HTTP/2 服務默認發往同一臺主機的所有請求共用一個套接字。

連接池減少請求的延遲(如 HTTP/2 不可用)。

gzip 壓縮下載大小可見。

通過響應緩存完全避免了網絡的重復請求。

OkHttpClient client = new OkHttpClient();String run(String url) throws IOException {
  Request request = new Request.Builder()
      .url(url)
      .build();

  Response response = client.newCall(request).execute();
  return response.body().string();
}

Retrofit

來自 Square 公司的 HTTP 客戶端,類型案例,可用于 Android 和 Java。Retrofit 會按照 HTTP API 生成 Java 接口。

public interface GitHubService {
    @GET("users/{user}/repos")
    Call<List<Repo>listRepos(@Path("user") String user);
}

Retrofit 類實現 GitHubService 接口。

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();

GitHubService service = retrofit.create(GitHubService.class);

來自 GitHubService 的每個 Call 都會向遠端 Web 服務器發送一個同步或異步的 HTTP 請求。

Call<List<Repo>> repos = service.listRepos("octocat");

JDeferred

Java 的 Deferred/Promise 庫,與 JQuery 的 Deferred/Promise 相似

  • Deferred 和 Promise 對象
  • Promise 回調:.then(…), .done(…), .fail(…), .progress(…), .always(…)
  • 同時處理多個 Promise - .when(p1, p2, p3, …).then(…)
  • Callable 和 Runnable - wrappers.when(new Runnable() {…})
  • 使用執行服務(ExecutorService)
  • Java Generics 支持: Deferred<Integer, Exception, Doubledeferred;, deferred.resolve(10);, deferred.reject(new Exception());,deferred.notify(0.80);,
  • 支持 Android
  • 可以使用 Java 8 Lambda

RxJava

RxJava – JVM 的 Reactive Extensions (響應式擴展) – 一個用于 Java VM 的庫,它通過可觀測序列構成異步及基于事件的程序。

它擴展了觀察者模式以支持數據/事件流,并添加了操作符,使你能以申明的方式組合處理序列,對一些事情進行抽象,比如低級線程、同步、線程安全和并發數據結構。

RxJava 常見的應用是在后臺線程運行一些計算或網絡請求,并在 UI 線程顯示結果(或錯誤):

Flowable.fromCallable(() -{
    Thread.sleep(1000); //  imitate expensive computation    return "Done";
})
  .subscribeOn(Schedulers.io())
  .observeOn(Schedulers.single())
  .subscribe(System.out::println, Throwable::printStackTrace);

Thread.sleep(2000); // <--- wait for the flow to finish

MBassador

MBassador 是一個輕量級、高性能的事件總線,它實現了發布/訂閱模式。它的設計目的是易用、功能豐富和可擴展,同時保持資源的高效利用和良好性能。

MBassador 高性能的核心在于一個專用的數據結構,這個數據結構提供了非阻塞讀功能以及在寫時最小化鎖競爭,因此它將并行讀/寫訪問造成的性能損耗降到最低。

  • 注解驅動
  • 分發的所有東西都會考慮類型層級
  • 同步和異步的消息分發
  • 可配置的引用類型
  • 消息過濾
  • 封裝消息
  • 多級優先層次處理
  • 自定義錯誤處理
// Define your listener
class SimpleFileListener{
    @Handler    
     public void handle(File msg){
      // do something with the file    
    }
}

// somewhere else in your codeMBassador bus = new MBassador();
Object listener = new SimpleFileListener();
bus.subscribe (listener);
bus.post(new File("/tmp/smallfile.csv")).now();
bus.post(new File("/tmp/bigfile.csv")).asynchronously();

Project Lombok

通過注解來減少 Java 中的重復性代碼,比如 getter 和 setter、非空檢查、生成 Builder 等。

  • val - 終級解決方案!簡化 final 局部變量定義。
  • @NonNull - 或者:了解我是怎樣停止擔心并愛上 NullPointerException 的。
  • @Cleanup - 怎么資源管理:方便而安全地調用 close() 方法。
  • @Getter / @Setter - 不再需要寫像 public int getFoo() {return foo;} 這樣的代碼。
  • @ToString - 不用啟動調試器就能觀察字段值:讓 Lombok 為你生成 toString!
  • @EqualsAndHashCode - 讓等值比較變得容易:在項目中由字段實現 hashCode 和 equals。
  • @NoArgsConstructor, @RequiredArgsConstructor and @AllArgsConstructor - 定制構造器:生成無參構造函數,對每個 final/非空 字段產生構造器,對每個字段產生構造器。
  • @Data - 它合并所有注解:相當于對所有字段應用 @ToString、@EqualsAndHashCode、@Getter,并對所有非 final 字段應用 @Setter,以及應用 @RequiredArgsConstructor!
  • @Value - 簡單創意不可變類。
  • @Builder - … 一切都很簡單:簡單直接地創建對象的 API!
  • @SneakyThrows - 大膽的拋出以前不能輕易拋出的異常!
  • @Synchronized - 正確的同步:不要暴露你的鎖。
  • @Getter(lazy=true) 懶加載是種美德!
  • @Log - 艦長日志,星歷 24435.7: “這是什么行?”

Simple Logging Facade for Java

Simple Logging Facade for Java(SLF4J)是對各種日志框架(比如 java.util.logging、logback、log4j 等)的簡單門面或者抽象,它讓用戶可以在開發時使用喜歡的日志框架。

簡單地說,庫和其它嵌入式組件考慮使用 SLF4J 來記錄日志,因為它們不能把自己選用的日志框架強加給用戶。另一方面,獨立的應用程序就不必在意是否使用 SLF4J。獨立的應用程序可以直接使用自己選用的日志框架。在使用 logback 的時候會有一個爭議,因為它是使用 SLF4J 來提供日志 API 的。

JUnitParams

參數化測試

@Test
@Parameters({"17, false", 
             "22, true" })
public void personIsAdult(int age, boolean valid) throws Exception {
  assertThat(new Person(age).isAdult(), is(valid));
}

與標準 JUnit Parametrised 運行器的主要區別:

  • 更明確 - 參數是測試方法的參數,而不是類中定義的字段
  • 更少代碼 - 不需要通過構造器來設置參數
  • 可以在一個類里混合參數化或非參數化的方法
  • 參數可以由 CSV 文本提供,也可以由專門的參數提供類提供
  • 參數提供類可以有任意多個參數提供方法,所以你可以對不同的情況分組
  • 可以由測試方法提供參數(而不是其它類或靜態方法)
  • 可以在 IDE 中看到實際的參數值(JUnit 的 Parametrised 中只有連續編號的參數)

Mockito

Java 中不錯的 mock 框架

//You can mock concrete classes, not just interfaces
LinkedList mockedList = mock(LinkedList.class);

//stubbing
when(mockedList.get(0)).thenReturn("first");
when(mockedList.get(1)).thenThrow(new RuntimeException());

//following prints "first"
System.out.println(mockedList.get(0));

//following throws runtime exception
System.out.println(mockedList.get(1));

//following prints "null" because get(999) was not stubbed
System.out.println(mockedList.get(999));

//Although it is possible to verify a stubbed invocation, usually it's just redundant
//If your code cares what get(0) returns, then something else breaks (often even before verify() gets executed).
//If your code doesn't care what get(0) returns, then it should not be stubbed. Not convinced? See here.
verify(mockedList).get(0);

Jukito

  • 結合了 JUnit、Guice 和 Mockito 的力量,聽起來很有技術含量。
  • 大大降低了自動 mock 的古板,使閱讀測試變得容易
  • 在測試對象的 API 變化時更有彈性
  • 通過 @Inject 注解的字段可以自動注入
  • 更容易將對象綁在一起,因此可以將單元測試擴展到部分集成測試
@RunWith(JukitoRunner.class)
public class EmailSystemTest {

  @Inject EmailSystemImpl emailSystem;
  Email dummyEmail;

  @Before
  public void setupMocks(
      IncomingEmails incomingEmails,
      EmailFactory factory) {
    dummyEmail = factory.createDummy();
    when(incomingEmails.count()).thenReturn(1);
    when(incomingEmails.get(0)).thenReturn(dummyEmail);
  }

  @Test
  public void shouldFetchEmailWhenStarting(
      EmailView emailView) {
    // WHEN
    emailSystem.start();

    // THEN
    verify(emailView).addEmail(dummyEmail);
  }
}

Awaitility

Awaitility 是一個小型的 DSL(領域專用語言),用于將異步操作同步化。

測試異步系統是件難事,不僅需要處理線程、超時和并發問題,測試代碼的意圖還可能被這些細節所掩蓋。Awaitility 是一個 DSL,它能以一個簡潔易讀的方式表達異步系統要做的事情。

@Test
public void updatesCustomerStatus() throws Exception {
    // Publish an asynchronous event:
    publishEvent(updateCustomerStatusEvent);
    // Awaitility lets you wait until the asynchronous operation completes:
    await().atMost(5, SECONDS).until(customerStatusIsUpdated());
    ...
}

Spock

用于企業的測試和規范框架。

class HelloSpockSpec extends spock.lang.Specification {
  def "length of Spock's and his friends' names"() {
    expect:
    name.size() == length

    where:
    name     | length
    "Spock"  | 5
    "Kirk"   | 4
    "Scotty" | 6
  }
}

WireMock

  • 模擬 HTTP 服務的工具
  • HTTP 響應頭,匹配 URL、標題和正文模式
  • 驗證請求
  • 在單元測試中運行、獨立運行或作為 WAR 應用運行
  • 通過 Java API、JSON 文件或者通過 HTTP 獲取的 JSON 來進行配置
  • 錄制/回放存根
  • 故障注入
  • 針對每個請求的條件代理
  • 瀏覽器代碼用于注入請求或更換請求
  • 有狀態的行為
  • 可配置響應延遲
{
    "request": {
        "method": "GET",
        "url": "/some/thing"
    },
    "response": {
        "status": 200,
        "statusMessage": "Everything was just fine!"
    }
}

原文:Java libraries you can't miss in 2017

鏈接:http://blog.jevsejev.io/2017/02/19/java-libraries-you-cannot-miss-in-2017/

譯者:邊城, Tocy, butta

 

來自:http://www.iteye.com/news/32170

 

 本文由用戶 liangshe093u 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!