Spring Framework 5.0是在Spring Framework 4.0之后將近四年內一次重大的升級。 在這個時間框架內,主要的發展之一就是Spring Boot項目的演變。
Spring Framework 5.0的最大特點之一是響應式編程(Reactive Programming)。 響應式編程核心功能和對響應式endpoints的支持可通過Spring Framework 5.0中獲得。 重要變動如下列表所示:
- 常規升級
- 對JDK 9運行時兼容性
- 在Spring Framework代碼中使用JDK 8特性
- 響應式編程支持
- 函數式Web框架
- Jigsaw的Java模塊化
- 對Kotlin支持
- 舍棄的特性
1. 常規升級
Spring Framework 5.0遵守JDK 8和Java EE 7規范。 基本上,這意味着以前的JDK和Java EE版本不再受支持了。
Spring Framework 5.0的一些重要基於Java EE 7規范如下所示:
- Servlet 3.1
- JMS 2.0
- JPA 2.1
- JAX-RS 2.0
- Bean Validation 1.1
對於幾個Java框架的最低支持版本有很多變化。下面的列表包含了一些重要框架的最低支持版本:
- Hibernate 5
- Jackson 2.6
- EhCache 2.10
- JUnit 5
- Tiles 3
下面列表顯示了受支持的服務器對應的版本:
- Tomcat 8.5+
- Jetty 9.4+
- WildFly 10+
- Netty 4.1+ (for web reactive programming with Spring Web Flux)
- Undertow 1.4+ (for web reactive programming with Spring Web Flux)
使用早期版本的任何前述規范/框架的應用程序需要在使用Spring Framework 5.0之前至少升級到上邊列出的版本。
2. 對JDK 9運行時兼容性
JDK 9預計將於2017年年中發布。Spring Framework 5.0期望與JDK 9運行時保持兼容性。
Tips
關於Java 9的發布時間,定在9月末,關於更多關於Java 9 的知識,可以訪問:Java 9揭秘
3. 在Spring Framework代碼中使用JDK 8特性
Spring Framework 4.x的基准版本是Java SE 6。這意味着它支持Java 6,7和8。必須支持Java SE 6和7對Spring Framework代碼的約束。 框架代碼不能使用Java 8中的任何新功能。所以,當世界其他地方升級到Java 8時,Spring Framework中的代碼(至少主要部分)僅限於使用早期版本的Java。
使用Spring Framework 5.0,基准版本是Java 8。Spring Framework代碼現在已升級為使用Java 8中的新特性。會改進更可讀和更有效的框架代碼。 使用的一些Java 8特性如下:
- 核心Spring接口中的Java 8 static 方法
- 基於Java 8反射增強的內部代碼改進
- 在框架代碼中使用函數式編程——lambdas表達式和stream流
4. 響應式編程支持
響應式編程是Spring Framework 5.0最重要的功能之一。
微服務通常基於事件通信的架構構建。 應用程序被設計為對事件(或消息)做出反應。
響應式編程提供了一種可選的編程風格,專注於構建應對事件的應用程序。
雖然Java 8沒有內置的響應式性編程支持,但是有一些框架提供了對響應式編程的支持:
Reactive Streams:嘗試定義與語言無關的響應性API。
Reactor:Spring Pivotal團隊提供的響應式編程的Java實現。
Spring WebFlux:啟用基於響應式編程的Web應用程序的開發。 提供類似於Spring MVC的編程模型。
5. 函數式Web框架
除了響應式特性之外,Spring 5還提供了一個函數式Web框架。
函數式Web框架提供了使用函數式編程風格來定義endpoints的功能。 這里顯示一個簡單的hello world示例:
RouterFunction<String> route =
route(GET("/hello-world"),
request -> Response.ok().body(fromObject("Hello World")));
函數式Web框架也可用於定義更復雜的路由(routes),如以下示例所示:
RouterFunction<?> route = route(GET("/todos/{id}"),
request -> {
Mono<Todo> todo = Mono.justOrEmpty(request.pathVariable("id"))
.map(Integer::valueOf)
.then(repository::getTodo);
return Response.ok().body(fromPublisher(todo, Todo.class));
})
.and(route(GET("/todos"),
request -> {
Flux<Todo> people = repository.allTodos();
return Response.ok().body(fromPublisher(people, Todo.class));
}))
.and(route(POST("/todos"),
request -> {
Mono<Todo> todo = request.body(toMono(Todo.class));
return Response.ok().build(repository.saveTodo(todo));
}));
需要注意的幾件重要事項如下:
RouterFunction
評估匹配條件,以將請求路由到適當的處理程序函數。- 定義了三個endpoints,兩個GET請求,一個POST請求,並將它們映射到不同的處理函數。
6. Jigsaw的Java模塊化
在Java 8之前,Java平台不是模塊化的。因此存在一些重要的問題:
- Platform Bloa Java模塊化在過去的幾十年中並沒有引起人們的關注。然而,通過物聯網(IOT-Internet of Things)和新的輕量級平台,如 Node.js迫切需要解決Java平台的膨脹問題。(最初版本的JDK的大小小於10 MB。最近的JDK版本需要超過200 MB。)
- JAR Hell 當ClassLoader找到一個類時,它不會看到是否有其他可用類的定義。 它立即加載找到的第一個類。 如果應用程序的兩個不同部分需要來自不同jar包的同一個類,那么它們就無法指定要加載類的jar包。
Open System Gateway initiative(OSGi)是在1999年開始的一項計划,它將模塊化引入到Java應用程序中。
每個模塊(module )定義如下:
- import 模塊使用的其他包
- export 模塊導出的包
每個模塊都可以有自己的生命周期。 它可以自行安裝,啟動和停止。
Jigsaw項目是Java Community Process(JCP)下的一個倡議,從Java 7開始,將模塊化納入Java。 它有兩個主要目標:
- 定義和實現JDK的模塊化結構
- 為Java平台上構建的應用程序定義模塊系統
Jigsaw將成為Java 9的一部分,Spring Framework 5.0將包含對Jigsaw模塊的基本支持。
7. 對Kotlin支持
Kotlin是一種靜態類型的JVM語言,可以實現具有更好的表達性,簡潔性和可讀性的代碼。 Spring框架5.0對Kotlin有很好的支持。
考慮一個簡單的Kotlin程序,說明一個data
類,如下所示:
import java.util.*
data class Todo(var description: String, var name: String, var
targetDate : Date)
fun main(args: Array<String>) {
var todo = Todo("Learn Spring Boot", "Jack", Date())
println(todo)
//Todo(description=Learn Spring Boot, name=Jack,
//targetDate=Mon May 22 04:26:22 UTC 2017)
var todo2 = todo.copy(name = "Jill")
println(todo2)
//Todo(description=Learn Spring Boot, name=Jill,
//targetDate=Mon May 22 04:26:22 UTC 2017)
var todo3 = todo.copy()
println(todo3.equals(todo)) //true
}
在不到10行代碼中,我們創建並測試了一個具有三個屬性和以下方法的數據bean:
- equals()
- hashCode()
- toString()
- copy()
Kotlin是強類型的。 但是不需要明確指定每個變量的類型:
val arrayList = arrayListOf("Item1", "Item2", "Item3")
// Type is ArrayList
命名參數允許你在調用方法時指定參數的名稱,從而保持更可讀的代碼:
var todo = Todo(description = "Learn Spring Boot",
name = "Jack", targetDate = Date())
Kotlin通過提供默認變量(it
)和諸如take
,drop
等方法使函數式編程更簡單:
var first3TodosOfJack = students.filter { it.name == "Jack"
}.take(3)
還可以為Kotlin中的參數指定默認值:
import java.util.*
data class Todo(var description: String, var name: String, var
targetDate : Date = Date())
fun main(args: Array<String>) {
var todo = Todo(description = "Learn Spring Boot", name = "Jack")
}
由於它的所有特性使代碼簡潔而富有表現力,我們希望Kotlin能夠成為一門語言。
8. 舍棄的特性
Spring Framework 5是一個主要的Spring版本,基准大幅度增加。 隨着Java,Java EE和其他幾個框架的基准版本的增加,Spring Framework 5刪除了對幾個框架的支持:
- Portlet
- Velocity
- JasperReports
- XMLBeans
- JDO
- Guava
如果你正在使用上面任何框架,建議計划遷移並使用Spring Framework 4.3——該框架一直支持到2019年。