2017你不應該錯過的Java庫包

banq發表於2017-02-20
下面是2017年你不應該錯過的Java庫包清單:

Guice
Guice是一個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);
 }
<p class="indent">


OkHttp
HTTP是現代網路的通訊方式。決定我們如何交換資料和媒體。 如果有效地執行HTTP通訊會使您的內容載入更快,並且節省頻寬。OkHttp是一個HTTP客戶端,高效是其特點:

(1)在HTTP / 2情況下支援對同一主機的所有請求能夠共享同一個socket。
(2)透過連線池降低請求延遲(如果HTTP / 2不可用)。
(3)透明GZIP壓縮下載大小。
(4)對響應進行快取,可以完全避免重複請求的網路。

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();
}
<p class="indent">



Retrofit
用於Android的型別安全的HTTP客戶端,能夠將HTTP API轉為Java介面。

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


Retrofit會產生上面GitHubService的實現類:

Retrofit retrofit = new Retrofit.Builder()
    .baseUrl("https://api.github.com/")
    .build();
 
GitHubService service = retrofit.create(GitHubService.class);
<p class="indent">


每個對建立的GitHubService類呼叫將對遠端伺服器產生一個同步或非同步的Http請求。

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


JDeferred
Java的Deferred/Promise庫類似於JQuery:

Deferred物件和Promise

Promise回撥: .then(…), .done(…), .fail(…), .progress(…), .always(…)

多個promises - .when(p1, p2, p3, …).then(…)

Callable 和 Runnable - wrappers.when(new Runnable() {…})
使用Executor Service

Java範型支援: Deferred<Integer, Exception, Doubledeferred;, deferred.resolve(10);, deferred.reject(new Exception());,deferred.notify(0.80);,

Android支援

Java 8 Lambda友好


RxJava
RxJava - JVM的反應式擴充套件Reactive Extension -使用可觀察序列來組合非同步和基於事件的程式。

它擴充套件了觀察者模式以支援資料/事件序列,並新增運算子,允許您以宣告方式組合序列,同時抽象出對低階執行緒,同步,執行緒安全和併發資料結構等問題的關注。

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
<p class="indent">


MBassador
MBassador是一種輕量級,高效能的事件匯流排,實現釋出訂閱模式。它為易於使用而設計,功能豐富且可擴充套件,同時保持資源效率和高效能。

MBassador的高效能核心是一個專門的資料結構,提供非阻塞讀取器,並最大限度地減少寫爭奪的鎖爭用,使併發讀/寫訪問的效能降低最小。

註釋驅動
遞送一切,尊重型別層次結構
同步和非同步訊息傳遞
可配置的引用型別
訊息過濾
包裝訊息
處理程式優先順序
自定義錯誤處理
擴充套件性

// Define your listener
class SimpleFileListener{
    @Handler
    public void handle(File msg){
      // do something with the file
    }
}

// somewhere else in your code
MBassador 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();
<p class="indent">


Lombok
使用註釋來減少Java中的重複程式碼,例如getters setters,not null檢查,生成Builder等。

val - 不會產生麻煩的final區域性變數。

@NonNull - 或者:我怎麼學會停止擔心和喜歡上了NullPointerException。

@Cleanup - 自動資源管理:安全地呼叫您的close()方法,沒有麻煩。

@Getter / @Setter - 不要再寫public int getFoo(){return foo;}。

@ToString - 無需啟動偵錯程式來檢視您的欄位:只需讓Lombok為您生成一個toString!

@EqualsAndHashCode - 從物件的欄位中生成hashCode和equals實現。

@NoArgsConstructor,@RequiredArgsConstructor和@AllArgsConstructor - 按順序構造的建構函式:生成不帶引數,每個final /非空欄位有一個引數或每個欄位有一個引數的建構函式。

@Data - 現所有欄位上都有@ToString,@EqualsAndHashCode,@Getter的快捷方式,所有非final欄位的@Setter和@RequiredArgsConstructor!

@Value - 編寫不可變的類非常容易。

@Builder - 沒有麻煩的花哨的API物件建立!

@SneakyThrows - 大膽地引發檢查異常,在沒有觸發他們之前!

@同步 - 同步:不要暴露你的鎖。

@Getter(lazy = true)懶惰是一種美德!


SLF4j
Simple Logging Facade for Java (SLF4J)用作各種日誌框架(例如java.util.logging,logback,log4j)的簡單封裝管理抽象,允許終端使用者在部署時插入所需的日誌框架。

簡而言之,嵌入式庫或元件應該考慮SLF4J的作為日誌記錄需求,因為該庫不會強加終端使用者選擇哪個日誌框架。 另一方面,對於獨立應用程式使用SLF4J並不一定有意義。獨立應用程式可以直接呼叫他們選擇的日誌框架。

JUnitParams
與標準JUnit的主要區別:

更明確 - params是在測試方法引數中,而不是類欄位
更少的程式碼 - 你不需要一個建構函式來設定引數
您可以在一個類中混合使用非引數方法的引數
引數可以作為CSV字串或引數提供程式類傳遞
引數提供程式類可以具有任意多個提供所需方法的引數,以便可以對不同的案例進行分組
你可以有一個提供引數的測試方法(不再有外部類或靜態)
您可以在IDE中檢視實際的引數值(在JUnit的Parametrised中,它只是連續的引數數量):

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


Mockito
單元測試框架:

//你可以模擬具體的類,而不僅僅是介面
 LinkedList mockedList = mock(LinkedList.class);

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

 //將列印 "first"
 System.out.println(mockedList.get(0));

 //將丟擲runtime exception
 System.out.println(mockedList.get(1));

 //將列印 "null" 因為get(999)沒有被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);
<p class="indent">


Jukito
集合 JUnit, Guice, 和 Mockito優點:
透過自動化,大大減少了樣板,導致更容易閱讀測試
引入對測試物件中的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);
  }
}
<p class="indent">


Awaitility
Awaitility是一種用於同步非同步操作的小型Java DSL。

測試非同步系統很困難。 它不僅需要處理執行緒,超時和併發問題,但測試程式碼的意圖可能被所有這些細節模糊。 Awaitility是一種DSL,允許您以簡潔易讀的方式表達非同步系統的期望。

@Test
public void updatesCustomerStatus() throws Exception {
    // Publish an asynchronous event:
    publishEvent(updateCustomerStatusEvent);
    // Awaitility讓你等待非同步操作完成
    await().atMost(5, SECONDS).until(customerStatusIsUpdated());
    ...
}
<p class="indent">


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
  }
}  
<p class="indent">


WireMock
模擬HTTP服務的工具:

HTTP響應stubbing存根,匹配HTTP的URL、頭部和正文內容
請求驗證
在單元測試中執行,作為獨立程式或作為WAR應用程式執行
可透過流暢的Java API,JSON檔案和透過HTTP的JSON進行配置
記錄/回放存根
故障注入
每次請求的條件代理
瀏覽器代理請求檢查和替換
狀態行為模擬
可配置的響應延遲

{
    "request": {
        "method": "GET",
        "url": "/some/thing"
    },
    "response": {
        "status": 200,
        "statusMessage": "Everything was just fine!"
    }
}

<p class="indent">





Java libraries you can't miss in 2017

相關文章