在本文中,咱們將討論 Spring 做爲最流行的 Java 框架之一的主要價值體現。html
最重要的是,咱們將嘗試理解 Spring 成爲咱們選擇框架的緣由。Spring 的詳細信息及其組成部分已在咱們 以前的教程中普遍介紹。 所以,咱們將跳過介紹性的「如何」部分,並主要關注「爲何」。java
在咱們開始任何關於 Spring 的討論以前,首先讓咱們瞭解爲何咱們首先須要使用任何框架。react
像 Java 這樣的通用編程語言可以支持多種應用程序。 更不用說 Java 天天都在積極地改進。web
此外,還有無數開源和專有庫在這方面支持 Java 。spring
那麼,咱們究竟爲何須要一個框架呢?老實說,使用框架來完成任務並非絕對必要的。可是,出於如下幾個緣由,使用一個一般是明智的:數據庫
咱們剛剛觸及了表面,咱們必須說,好處難以忽視。但這不多是積極的,因此要注意的是:編程
坦率地說,在軟件開發和框架中沒有什麼銀彈,Java 固然也不例外。所以,應該根據上下文來選擇哪一個框架或不用框架。json
在本文的最後,咱們將更好地作出關於 Java 中的 Spring 的決策。設計模式
在咱們開始對 Spring 框架進行定性評估以前,讓咱們仔細看看 Spring 生態系統是什麼樣子的。緩存
Spring 是在2003年的某個時候出現的,當時 Java 企業版發展迅速,開發企業應用程序很使人興奮,但也很乏味!
Spring 最初是 Java 的 一個控制反轉 (IoC)容器。咱們仍然主要將 Spring 與它聯繫起來,事實上,它構成了框架的核心,以及在此基礎上開發的其餘項目。
Spring 框架 被劃分爲多個模塊,這使得在任何應用程序中均可以很容易地選擇要使用的部分:
可是,Spring 更有價值的是一個強大的生態系統,這個生態系統多年來一直在發展,而且還在不斷髮展。 它們的結構是 Spring 項目 ,它們是在 Spring 框架之上開發的。
儘管 Spring 項目的清單很長,並且一直在變化,但仍有一些值得一提的地方:
毋庸置疑,這是對 Spring 所提供內容的一個至關抽象的介紹。可是它爲咱們提供了關於 Spring 的組織和廣度的足夠的基礎,以便咱們進一步討論。
人們習慣於添加一個 hello world 程序來了解任何新技術。
讓咱們來看看 Spring 如何讓編寫一個不只僅是 Hello World 的程序變得輕鬆自如。咱們將建立一個應用程序,該應用程序將 CRUD 操做公開爲一個域實體(如由內存數據庫支持的僱員)的 REST API。更重要的是,咱們將使用基本認證來保護咱們的突變端點。最後,沒有好的、舊的單元測試,任何應用程序都不能真正完成。
咱們將使用 Spring Initializr 設置 Spring Boot 項目,這是一個方便的在線工具,能夠引導具備正確依賴項的項目。咱們將添加 Web、JPA、H2 和 Security 做爲項目依賴項,以正確地得到 Maven 配置設置。 更多細節引導在咱們之前的文章之一。
因爲幾乎不須要作什麼,咱們已經準備好定義域模型和持久性。
讓咱們首先將 Employee 定義爲一個簡單的 JPA 實體:
@Entity
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotNull
private String firstName;
@NotNull
private String lastName;
// Standard constructor, getters and setters
}
複製代碼
注意,咱們在實體定義中包含了自動生成的 id 。
如今咱們必須爲實體定義 JPA 存儲庫。這就是 Spring 使它變得很是簡單的地方:
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
List<Employee> findAll();
}
複製代碼
咱們所要作的就是定義一個這樣的接口,Spring JPA 將爲咱們提供一個用默認和自定義操做充實的實現。至關整潔!在咱們的其餘文章中能夠找到更多關於 使用 Spring Data JPA 的細節。
如今咱們必須定義一個網絡控制器路由和處理咱們的傳入請求:
@RestController
public class EmployeeController {
@Autowired
private EmployeeRepository repository;
@GetMapping("/employees")
public List<Employee> getEmployees() {
return repository.findAll();
}
// Other CRUD endpoints handlers
}
複製代碼
實際上,咱們所要作的就是對這個類使用註解並定義路由元信息以及每一個處理程序方法。
在咱們的前一篇文章中詳細討論瞭如何使用 Spring REST 控制器。
因此如今咱們已經定義了全部內容,可是如何保護建立或刪除員工之類的操做呢?咱們不但願對這些端點進行未經身份驗證的訪問!
Spring Security 在這方面很是出色:
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.antMatchers(HttpMethod.GET, "/employees", "/employees/**")
.permitAll()
.anyRequest()
.authenticated()
.and()
.httpBasic();
}
// other necessary beans and definitions
}
複製代碼
這裏有 更多的細節須要注意理解 ,但最重要的一點是咱們只容許 GET 操做不受限制的聲明式方式。
如今咱們已經作了全部的事情,可是等等,咱們如何測試這個呢?
讓咱們看看 Spring 是否可讓編寫 REST 控制器的單元測試變得更容易:
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class EmployeeControllerTests {
@Autowired
private MockMvc mvc;
@Test
@WithMockUser()
public void givenNoEmployee_whenCreateEmployee_thenEmployeeCreated() throws Exception {
mvc.perform(post("/employees").content(
new ObjectMapper().writeValueAsString(new Employee("First", "Last"))
.with(csrf()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status()
.isCreated())
.andExpect(jsonPath("$.firstName", is("First")))
.andExpect(jsonPath("$.lastName", is("Last")));
}
// other tests as necessary
}
複製代碼
正如咱們所看到的,Spring 爲咱們提供了必要的基礎設施來編寫簡單的單元和集成測試,不然這些測試將依賴於要初始化和配置的 Spring 上下文。
最後,咱們如何運行這個應用程序?這是 Spring Boot 的另外一個有趣的方面。儘管咱們能夠將其打包爲常規應用程序並傳統上部署在 Servlet 容器上。
但這有什麼好玩的!Spring Boot 附帶一個嵌入式 Tomcat 服務器:
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
複製代碼
這是一個預先建立的類,做爲引導程序的一部分,具備使用嵌入式服務器啓動此應用程序的全部必要細節。
此外,這是高度可定製的。
雖然選擇使用框架相對容易,但在框架之間進行選擇一般會讓咱們的選擇變得艱鉅。 但爲此,咱們必須至少粗略地瞭解 Spring 提供的功能有哪些替代方案。
如前所述,Spring 框架及其項目爲企業開發人員提供了普遍的選擇。若是咱們對當代 Java 框架作一個快速評估,它們甚至不能與 Spring 提供給咱們的生態系統相提並論。
然而,對於特定的領域,它們確實造成了一個使人信服的論據來選擇替代方案:
除了這些以外,還有一些新功能提供了比特定領域更普遍的支持,但仍然沒有涵蓋 Spring 必須提供的全部內容:
顯然,徹底迭代這個列表既沒必要要也不可行,可是咱們在這裏獲得了普遍的概念。
最後,咱們構建了全部必需的上下文來解決咱們的核心問題,爲何是 Spring?咱們瞭解框架能夠幫助咱們開發複雜的企業應用程序的方式。
此外,咱們瞭解咱們針對特定問題所作的選擇,例如 Web,數據訪問,框架方面的集成,尤爲是 Java 。
如今,在全部這些當中,Spring 的亮點在哪裏?讓咱們來探索一下。
任何框架流行的一個關鍵方面是開發人員使用它是多麼容易。Spring 經過多個配置選項和約定優於配置使開發人員能夠輕鬆啓動,而後準確配置他們須要的內容。
像 Spring Boot 這樣的項目使得引導一個複雜的 Spring 項目變得很是簡單。更不用說,它有優秀的文檔和教程來幫助任何人入門。
Spring 受歡迎的另外一個關鍵方面是其高度模塊化的特性。 咱們能夠選擇使用整個 Spring 框架或僅使用必要的模塊。 此外,咱們能夠根據須要選擇包含一個或多個 Spring 項目。
並且,咱們還能夠選擇使用 Hibernate 或 Struts 等其餘框架!
雖然 Spring 不支持全部 Java EE 規範,但它支持全部技術,一般在必要時提升對標準規範的支持。 例如,Spring 支持基於 JPA 的存儲庫,所以切換提供程序變得微不足道。
此外,Spring 支持行業規範,如 Spring Web Reactive 下的 Reactive Stream 和 Spring HATEOAS 下的 HATEOAS 。
採用任何框架在很大程度上還取決於測試構建在其上的應用程序是多麼容易。 Spring 的核心是倡導並支持測試驅動開發(TDD)。
Spring 應用程序主要由 POJO 組成,這天然使單元測試相對簡單得多。 可是,Spring 確實爲 MVC 等場景提供了 Mock 對象,不然單元測試變得複雜。
Spring 在創新、採用和標準化方面有着悠久的歷史。多年來,它已經足夠成熟,能夠成爲大型企業應用程序開發中最多見問題的默認解決方案。
更使人興奮的是積極的開發和維護。天天都在開發對新語言特性和企業集成解決方案的支持。
最後但並不是最不重要的是,任何框架甚至類庫都經過創新在行業中生存下來,並且沒有比社區更好的創新場所。 Spring 是由 Pivotal Software 領導的開源軟件,由大型組織和我的開發者組成的支持。
這就意味着它仍然具備背景意義,並且每每具備將來主義色彩,這一點從它旗下項目的數量就能夠明顯看出。
有各類各樣的應用程序能夠從不一樣級別的 Spring 使用中受益,而且這種應用程序的變化與 Spring 的增加速度同樣快。
可是,咱們必須理解 Spring 和其餘框架同樣,有助於管理應用程序開發的複雜性。它幫助咱們避免常見的陷阱,並使應用程序隨着時間的推移保持可維護性。
這是以額外的資源足跡和學習曲線爲代價的,儘管可能很小。 若是確實存在一個足夠簡單而且預計不會變得複雜的應用程序,那麼根本不使用任何框架可能會帶來更多益處!
在本文中,咱們討論了在應用程序開發中使用框架的好處。咱們還進一步簡要的討論了 Spring 框架。
在討論這個主題時,咱們還研究了一些可用於 Java 的替代框架。
最後,咱們討論了促使咱們選擇 Spring 做爲 Java 選擇框架的緣由。
不過,咱們應該在本文的結尾給出一些建議。儘管聽起來頗有說服力,但在軟件開發中一般沒有單一的、通用的解決方案。
所以,咱們必須運用咱們的智慧,爲咱們要解決的具體問題選擇最簡單的解決辦法。
送福利啦~ 近期將以前已翻譯文章,整理成PDF。
在公衆號後臺回覆:002 便可領取哦~
後續也會不斷更新PDF的內容,敬請期待!