阅读更多

3顶
0踩

开源软件
这些开源库非常棒,我已经将它们整理成参考清单,附上简短的功能清单连同案例一同分享。

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
来自: 开源中国
3
0
评论 共 2 条 请登录后发表评论
2 楼 th270 2017-03-04 20:40
很喜欢Lombok 这个框架! 马上使用立马见效果!其他的几个框架还真的不知道怎么使用,可以讲解详细点么?
1 楼 gandilong 2017-03-01 09:32
我喜欢那个MBassador

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 驱动和应用程序中获取精确时间

    在驱动和应用程序中获取精确的时间,可以精确到us,对于定时要求严的程序很有用。

  • windows 驱动系统时

        在编程中,我们经常需要获得系统时间或是从启动开始的毫秒数,启动毫秒数在ring3我们可以使用GetTickCount()函数来获得,在ring0中也有一个对应的函数KeQueryTickCount(),不过单靠这个函数还不够,因为它参数中返回的不是直接的“毫秒”数,而是“滴答”数,而一个“滴答”在不同的环境中表示的时间是不同的,因此我们还要先使用另一个函数来辅助:KeQueryTimeIn

  • 驱动中获得系统时间(转)

    驱动中获得系统时间(转) 2007年09月06日 星期四 9:58 1. KeQuerySystemTime() 获得当前的 GMT System Time. 这是一个从 1601-01-01 以来的计数(单位是 100ns) 2. ExSystemTimeToLocalTime() 将 GMT System Time 值转换成当前时区的 Local System Time. 3. Rtl

  • Kenel中的时间处理函数

    //得到当前系统时间 LARGE_INTEGER Systemtime,LocalTime; TIME_FIELDS FildsTime; KeQuerySystemTime(&Systemtime); ExSystemTimeToLocalTime(&Syste

  • 2.6 Windows驱动开发:使用IO与DPC定时器

    本章将继续探索驱动开发中的基础部分,定时器在内核中同样很常用,在内核中定时器可以使用两种,即IO定时器,以及DPC定时器,一般来说IO定时器是DDK中提供的一种,该定时器可以为间隔为N秒做定时,但如果要实现毫秒级别间隔,微秒级别间隔,就需要用到DPC定时器,如果是秒级定时其两者基本上无任何差异,本章将简单介绍`IO/DPC`这两种定时器的使用技巧。

  • Windows驱动开发之获取系统时间

    驱动开发之获取系统时间

  • linux驱动31:获取当前时间

    获取当前时间

  • Linux驱动中获取系统时间

    最近在做VoIP方面的驱动,总共有16个FXS口和FXO口依次初始化,耗用的时间较多。准备将其改为多线程,首先需要确定哪个环节消耗的时间多,这就需要获取系统时间。 #include &lt;linux/time.h&gt;  /*头文件*/ struct timeval time_now; unsigned long int time_num;//获取的时间 ...

  • linux驱动层获取当前的系统时间

    #include #include #include /*添加到合适位置*/ struct timex txc; struct rtc_time tm; do_gettimeofday(&(txc.time)); rtc_time_to_tm(txc.time.tv_sec,&tm); printk(“UTC time :%d-%d-%d %d:%d:%d /n”,tm.tm_year

  • Linux内核中获取当前时间

    7.2. 获知当前时间内核代码能一直获取一个当前时间的表示, 通过查看 jifies 的值. 常常地, 这个值只代表从最后一次启动以来的时间, 这个事实对驱动来说无关, 因为它的生命周期受限于系统的 uptime. 如所示, 驱动可以使用 jiffies 的当前值来计算事件之间的时间间隔(例如, 在输入驱动中从单击中区分双击或者计算超时). 简单地讲, 查看

  • 在内核中如何获得系统的日期和时间

    WDM驱动中可以按照以下步骤: 1. 用 KeQuerySystemTime() 获得当前的 GMT System Time. 这是一个从 1601-01-01 以来的计数(单位是 100ns)。 2. 调用 ExSystemTimeToLocalTime() 将 GMT System Time 值转换成当前时区的 Local System Time. 3. 用 RtlTimeToTimeFiel...

  • 关于KeUpdateSystemTime原型

    最近学驱动,遇到KeUpdateSystemTime这个玩意原型百度了一下,看到有人说; VOID  ; KeUpdateSystemTime (  ;       IN KIRQL PreviousIrql,  ;       IN KTRAP_FRAME TrapFrame  ;       )     使用老是有问题,找了WRK里面原型其实是 NTSTATUS

  • WDM在不同Windows版本上的音频支持

    "Windows音频驱动"翻译系列总目录:https://blog.csdn.net/danteLiujie/article/details/102530417 目录 1. 实现音频模块通信 1.1. 为什么使用音频模块? 1.2. 音频模块定义 1.3. 通用音频定义 1.4. 架构 发送命令 音频模块客户端的模块通知 启用,禁用和常规拓扑信息 1.5. 音频模块DDI ...

  • 时间戳和日期时间Timestamp的转化

    这两天在学springMVC,写了个商品管理系统demo。 遇到一个难点,日期时间是private Timestamp createtime;所以AJAX请求会报400参数错误,因为传createtime有问题, 后来想了下,前端做个处理,将时间戳转为Timestamp格式,下面贴JS代码:/** * 格式化显示时间日期 * @param time Unix时间戳格式, 如

  • 如何在内核中获得当前系统时间

    在 Windows NT 内核中你是无法使用 time.h 获取当前系统时间的,这个时候你需要用到 Wdm.h(你可以 include Wdm.h, Ntddk.h, 或 Ntifs.h)里面提供的 KeQuerySystemTime() 函数。这个函数和相关头文件需要 Windows 2000, Windows Vista 或者 Windows 7 等 NT 系统。 函数原型...

  • windows 使用GetLocalTime()和GetSystemTime()所获得的时间不同

    [cpp] view plain copy #include    //#include    #include    //#pragma comment(lib,"kernel32.lib")   //using namespace std;   void main()   {   SYSTEMTIME systime;   GetLocalTime

Global site tag (gtag.js) - Google Analytics