为了把大家从越来越多的技术水文中拯救出来,"大公司技术博客" 将良心推送国内外大公司的优质干货文,如 Facebook, Google, Medium, GitHub、Hacker News、Quora(嗯,我知道很多国外的文章你点不开,或者是英文的你懒得看)等。技术创新、深度研究、未来趋势,这里都有。当然了,这么说无非就是希望你点下 关注 。
这篇文章介绍了 2017 年最流行、最好用的 Java 库,从事 Java 或 Android 开发的同学不要错过了。
Guice (发音同
) 是 Google 开发的一款适用于 Java 6+ 的依赖注入框架。
- juice
- #依赖注入方式public class DatabaseTransactionLogProvider implements Provider < TransactionLog > {@Inject Connection connection;
- public TransactionLog get() {
- return new DatabaseTransactionLog(connection);
- }
- }
- #FactoryModuleBuilder generates factory using your interfacepublic interface PaymentFactory {
- Payment create(Date startDate, Money amount);
- }
OkHttp 是目前非常流行的网络请求框架。高效地执行 Http 请求能够让你的数据加载更快、带宽消耗更少。
OkHttp 的高效率来自以下几个特性:
- 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();
- }
这是一款 Square 公司开发的针对 Android 和 Java 的类型安全 Http Client。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);
利用这个接口,我们可以向远程服务器直接执行同步或异步的 Http Request。
- Call<List<Repo>> repos = service.listRepos("octocat");
这是一款类似 JQuery 的 Java Deferred/Promise 库,具备如下特性:
,
- .then(…)
,
- .done(…)
,
- .fail(…)
,
- .progress(…)
- .always(…)
- .when(p1, p2, p3, …).then(…)
- wrappers.when(new Runnable() {…})
,
- Deferred
,
- deferred.resolve(10);
,
- deferred.reject(new Exception());
,
- deferred.notify(0.80);
RxJava – JVM 的响应式扩展 – a library for composing asynchronous and event-based programs using observable sequences for the Java VM.
它在观察者模式的基础上进行了扩展,支持 data/events 的序列化,增加了多种操作符来组装数据序列,而且,你完全不用关心底层的线程切换、同步机制、线程安全及并发数据结构。
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 高性能的最关键原因在于一种特殊的数据结构,这种数据结构可最大限度减小锁竞争。
- // 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();
使用注解 annotation 来减少代码重复,例如 getter、setter、not null 检查、生成 Builder 等。下面有一些 Project Lombok 的 feature:
- final String foo = example.get(0); var foo = example.get(0);
了;
- public int getFoo() {return foo;}
,
- @ToString
,
- @EqualsAndHashCode
对所有变量,
- @Getter
对所有非 final 变量,
- @Setter
- @RequiredArgsConstructor
是一个日志库抽象层,并非真正的日志库,可以支持不同的日志实现,如
,
- java.util.logging
,
- logback
。开发者可以利用这个抽象层来随时切换底层日志实现框架。
- log4j
实际上, 所提供的核心 API 是一些接口以及一个 的工厂类。在使用 的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。 提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。
那么什么时候使用 比较合适呢?
如果你开发的是类库或者嵌入式组件,那么就应该考虑采用 ,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用 的必要。假设你打算将你使用 的产品卖给要求使用 的用户时,面对成千上万的 调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用 ,那么这种转换将是非常轻松的事情。
- @Test
- @Parameters({"17, false",
- "22, true" })
- public void personIsAdult(int age, boolean valid) throws Exception {
- assertThat(new Person(age).isAdult(), is(valid));
- }
它的优势如下:
Tasty mocking framework for unit tests in Java
- //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);
对了,po 主花费一个半小时时间阅读、搜索、编辑。而且还有更多来自世界大公司的优质内容在加工中…
这都不关注!?
来源: http://www.tuicool.com/articles/ayuAzmA