知識庫 / Spring RSS 訂閱

選擇Spring作為你的Java框架?

Spring
HongKong
11
01:21 PM · Dec 06 ,2025

1. 概述

本文將深入探討 Spring 作為最流行的 Java 框架,其核心價值主張。

更重要的是,我們將嘗試理解 Spring 成為我們首選框架的原因。 Spring 及其組成部分的詳細信息,在之前的教程中已經得到充分的闡述。因此,我們將跳過基礎的“如何”部分,主要關注“為什麼”的原因。

2. 為什麼要使用任何框架?

在深入討論 Spring 之前,我們首先需要理解一下,我們為什麼需要使用任何框架。

Java 這樣的通用編程語言能夠支持各種各樣的應用程序。 此外,Java 每天都在不斷地改進和完善。

而且,還有無數的開源和專有庫來支持 Java 在此方面。

那麼,我們為什麼需要使用框架呢? 坦白説,使用框架來完成一項任務並非絕對必要。 但是,出於以下幾個原因,使用框架通常是明智之舉:

  • 幫助我們專注於核心任務,而不是與其相關的樣板代碼
  • 將多年經驗以設計模式的形式匯聚起來
  • 幫助我們遵守行業和監管標準
  • 降低應用程序的總擁有成本

我們剛才只是觸及了冰面,並且可以肯定地説,這些好處很難忽視。 但是,並非所有事情都積極,所以有什麼“陷阱”呢:

  • 迫使我們以特定方式編寫應用程序
  • 綁定到特定語言和庫版本
  • 增加了應用程序的資源佔用

坦白説,在軟件開發中沒有萬能的解決方案,框架當然也不例外。 因此,選擇使用哪個框架或不使用任何框架應該由上下文驅動。

希望通過本文,我們能夠更好地為有關 Spring 在 Java 中的決策做好準備。

3. Spring 生態系統概述

在對 Spring Framework 進行定性評估之前,讓我們更深入地瞭解 Spring 生態系統。

在 2003 年,Spring 誕生於 Java Enterprise Edition 快速發展、構建企業應用程序既令人興奮又繁瑣的時期。

Spring 最初是一個用於 Java 的依賴倒置 (IoC) 容器。 我們仍然主要將 Spring 與其聯繫起來,事實上,它構成了框架和在此基礎上開發的其他項目的核心。

3.1. Spring 框架

Spring 框架被劃分為模塊,這使得它很容易選擇性地使用,以適應任何應用程序的需求:

  • 核心:提供核心功能,如依賴注入 (Dependency Injection)、國際化 (Internationalisation)、驗證 (Validation) 和麪向切面編程 (Aspect Oriented Programming)
  • 數據訪問:通過 JTA (Java Transaction API)、 JPA (Java Persistence API) 和 JDBC (Java Database Connectivity) 支持數據訪問
  • Web:支持 Servlet API (Spring MVC) 和最近的 Reactive API (Spring WebFlux),此外還支持 WebSockets、STOMP 和 WebClient
  • 集成:通過 JMS (Java Message Service)、 JMX (Java Management Extension) 和 RMI (Remote Method Invocation) 支持與企業 Java 的集成
  • 測試:通過 Mock Objects、測試模版、上下文管理和緩存,廣泛支持單元測試和集成測試

3.2. Spring 項目

但使 Spring 更有價值的是圍繞它發展起來的強大生態系統,並且它在不斷演進。這些項目被結構化為 Spring 項目,這些項目建立在 Spring 框架之上進行開發。

雖然 Spring 項目的數量眾多且不斷變化,但以下項目值得一提:

  • Boot:提供一套高度有意見但可擴展的模板,幾乎可以在短時間內創建基於 Spring 的各種項目。它使創建獨立的 Spring 應用程序,並使用嵌入式 Tomcat 或類似容器變得非常容易。
  • Cloud:提供支持,可以輕鬆地開發一些常見的分佈式系統模式,例如服務發現、斷路器和 API 網關。它有助於減少在本地、遠程或託管平台上部署這些樣板代碼的努力。
  • Security:提供一種強大的機制,可以以高度可定製的方式為基於 Spring 的項目開發身份驗證和授權。通過最小的聲明式支持,我們能夠獲得對會話固定、點擊劫持和跨站請求偽造等常見攻擊的保護。
  • Mobile:提供檢測設備並相應地調整應用程序行為的功能。此外,還支持面向設備的視圖管理、站點偏好管理和站點切換器。
  • Batch:提供用於開發面向企業系統的批處理應用程序的輕量級框架,例如數據歸檔。它具有直觀的支持,包括調度、重啓、跳過、收集指標和日誌記錄。此外,它還支持通過優化和分區,以高吞吐量的工作負載進行擴展。

Needless to say that this is quite an abstract introduction to what Spring has to offer. But it provides us enough ground with respect to Spring’s organization and breadth to take our discussion further.

4. Spring in Action

為了理解任何新技術,通常的做法是添加一個“Hello, World”程序。

讓我們看看 Spring 如何讓編寫不僅僅是“Hello, World”的程序變得輕而易舉。我們將創建一個應用程序,它將以 REST API 的形式暴露 CRUD 操作,用於一個域實體(例如 Employee),並使用內存數據庫進行支持。更重要的是,我們還將使用基本身份驗證來保護我們的修改端點。最後,任何應用程序都不能沒有好的單元測試。

4.1. 項目設置

我們將使用 Spring Initializr 設置我們的 Spring Boot 項目。Spring Initializr 是一款便捷的在線工具,可用於快速啓動項目並添加所需的依賴項。我們將添加 Web、JPA、H2 和 Security 作為項目依賴項,以確保 Maven 配置正確設置。

關於項目啓動的更多詳細信息,請參閲我們之前的文章。

4.2. 領域模型與持久化

由於工作量有限,我們已經準備好定義我們的領域模型和持久化方案。

首先,讓我們定義 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 的信息,請參考我們的其他文章。

4.3. 控制器

現在我們需要定義一個 Web 控制器,用於路由和處理我們收到的請求:

@RestController
public class EmployeeController {
    @Autowired
    private EmployeeRepository repository;
    @GetMapping("/employees")
    public List<Employee> getEmployees() {
        return repository.findAll();
    }
    // Other CRUD endpoints handlers
}

實際上,我們只需要註釋類並定義路由元信息,以及每個處理方法。

關於 Spring REST 控制器的使用,請參考我們在上一篇文章中詳細的説明。

4.4. 安全性

現在我們已經定義了所有內容,但如何確保對創建或刪除員工等操作的安全性呢?我們不想讓未經身份驗證的訪問者訪問這些端點!

Spring Security 在這一領域發揮着重要作用:

@EnableWebSecurity
public class WebSecurityConfig {
 
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http
          .authorizeRequests()
            .antMatchers(HttpMethod.GET, "/employees", "/employees/**")
            .permitAll()
          .anyRequest()
            .authenticated()
          .and()
            .httpBasic();
        return http.build();
    }
    // other necessary beans and definitions
}

這裏有更多細節需要注意以理解,但最重要的要點是我們僅允許使用未受限制的 GET 操作的聲明式方式

4.5. 測試

現在我們已經完成了所有操作,但等等,我們如何進行測試呢?

讓我們看看 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 上下文的初始化和配置。

4.6. 運行應用程序

最後,我們如何運行這個應用程序? 這也是 Spring Boot 中一個有趣的方面。 儘管我們可以將其打包為常規應用程序並在 Servlet 容器上傳統地部署,但……

但是,這其中藴含着樂趣! Spring Boot 內置了一個 Tomcat 服務器

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

這是一個預先創建的類,作為 Bootstrap 的一部分提供,包含了使用嵌入式服務器啓動此應用程序所需的所有必要信息。

此外,它高度可定製。

5. Spring 替代方案

選擇使用框架相對容易,但選擇合適的框架卻可能讓人望而卻步,因為選擇太多了。不過,為了做出明智的決定,我們至少需要對 Spring 提供的各種功能有哪些替代方案有一個大致的瞭解。

正如我們之前討論的,Spring 框架及其相關項目為企業開發者提供了廣泛的選擇

如果我們快速評估一下當今流行的 Java 框架,它們幾乎無法與 Spring 提供的生態系統相媲美。

然而,在特定領域,它們仍然可以作為替代方案提供有力的論據:

  • Guice:為 Java 應用程序提供強大的 IoC 容器
  • Play:作為具有反應式支持的 Web 框架,非常適合
  • Hibernate:一個成熟的數據訪問框架,支持 JPA

除了這些之外,還有一些較新的添加項,它們提供比特定領域更廣泛的支持,但仍然無法涵蓋 Spring 提供的所有功能:

  • Micronaut:專為雲原生微服務設計的 JVM 級框架
  • Quarkus:一個承諾更快的啓動時間和更小的佔位符的新一代 Java 堆棧

顯然,完全遍歷這個列表是不必要的,但我們仍然可以從中獲得一個大致的瞭解。

6. 為什麼選擇 Spring?

我們已經構建了所有必要的上下文,以回答我們核心的問題:為什麼選擇 Spring? 我們理解框架如何幫助我們開發複雜的企業級應用。

此外,我們同樣理解針對特定問題(如 Web、數據訪問和集成)的各種選擇,尤其是在 Java 領域。

現在,在所有這些選項中,Spring 表現如何? 讓我們來探索一下。

6.1. 可用性

任何框架的受歡迎程度,關鍵在於其易用性,即開發者對其的易用程度。Spring 通過多種配置選項和“約定優於配置”的設計理念,使得開發者能夠輕鬆地啓動並精確地配置所需的一切。

像 Spring Boot 這樣的項目,幾乎將複雜的 Spring 項目啓動變得輕而易舉。此外,它還提供卓越的文檔和教程,幫助任何新手快速上手。

6.2. 模塊化

Spring 流行的一個關鍵因素是其高度模塊化的特性。我們可以選擇使用整個 Spring 框架,也可以只使用所需的模塊。此外,我們還可以根據需要可選地包含一個或多個 Spring 項目

另外,我們還可以使用像 Hibernate 或 Struts 這樣的其他框架!

6.3. 符合性

儘管 Spring 不支持所有 Jakarta EE 規範,但它支持所有其技術,並且在必要時,通常會改進其支持,使其超過標準規範。例如,Spring 支持基於 JPA 的倉庫,從而使切換提供商變得輕而易舉。

此外,Spring 支持諸如 Reactive Stream 這樣的行業規範,在 Spring Web Reactive 和 Spring HATEOAS 下提供支持。

6.4. 可測試性

採用任何框架很大程度上也取決於構建在其之上的應用程序的可測試性。Spring 在其核心中 倡導並支持測試驅動開發 (TDD)。

Spring 應用程序主要由 POJO 組成,這自然使單元測試變得更加簡單。但是,Spring 確實提供了 Mock 對象,用於解決 MVC 等複雜場景下的單元測試問題。

6.5 成熟度

Spring 擁有悠久的創新、採用和標準化歷史。多年來,它已經發展到足以成為大多數大型企業應用開發中常見問題的默認解決方案。

更令人興奮的是,它正在積極開發和維護中。對新語言特性和企業集成解決方案的支持每天都在不斷開發中。

6.6. 社區支持

最後但凡,任何框架乃至庫的生存都依賴於創新,而社區無疑是創新的最佳場所。Spring 是一個開源項目,由 Pivotal 軟件主導,並得到眾多組織和個人開發者的大力支持。

這意味着它仍然保持着前瞻性和創新性,這一點可以從其涵蓋的項目數量中一目瞭然。

7. 不使用 Spring 的原因

有多種應用程序可以從不同程度的 Spring 使用中獲益,並且隨着 Spring 的快速發展而不斷變化。

然而,我們必須理解的是,像 Spring 這樣任何其他框架都可以在管理應用程序開發複雜性方面提供幫助。它幫助我們避免常見的陷阱,並隨着應用程序的增長保持應用程序的可維護性。

但這 代價是額外的資源佔用和學習曲線,即使這個曲線很小。如果存在足夠簡單且不預計會變得複雜的應用程序,或許最好完全不使用任何框架!

8. 結論

在本文中,我們探討了使用框架在應用程序開發中的優勢,並簡要討論了 Spring 框架。

同時,我們還考察了 Java 中其他可用的框架。

最後,我們討論了促使我們選擇 Spring 框架的原因。

我們應該以一條建議結束本文,儘管它聽起來多麼有説服力,軟件開發中通常沒有通用的、一刀切的解決方案

因此,我們必須在選擇解決特定問題的最簡單解決方案時運用我們的智慧。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.