【Java企業生態系統的演進】從單體J2EE到云原生微服務

Java企業生態系統的演進:從單體J2EE到云原生微服務

目錄標題

  • Java企業生態系統的演進:從單體J2EE到云原生微服務
    • 摘要
    • 1. 引言
    • 2. 整體框架演進:從原始Java到Spring Cloud
      • 2.1 原始Java階段(1995-1999)
      • 2.2 J2EE階段(1999-2004)
      • 2.3 輕量級框架階段(2002-2006)
      • 2.4 Spring框架階段(2004-2012)
      • 2.5 Spring Boot階段(2014-2018)
      • 2.6 Spring Cloud階段(2015-至今)
    • 3. 數據訪問技術演進:從JDBC到Spring Data
      • 3.1 JDBC階段(1997-2002)
      • 3.2 DAO模式階段(2000-2005)
      • 3.3 ORM(Hibernate)階段(2002-2008)
      • 3.4 JPA階段(2006-2012)
      • 3.5 Spring Data階段(2011-至今)
    • 4. Web開發范式演進:從Servlet/JSP到前后端分離
      • 4.1 Servlet/JSP階段(1997-2003)
      • 4.2 Struts階段(2000-2006)
      • 4.3 JSF階段(2004-2010)
      • 4.4 Spring MVC階段(2005-2015)
      • 4.5 RESTful API階段(2010-2017)
      • 4.6 前后端分離階段(2015-至今)
    • 5. 演進模式分析與展望
      • 5.1 演進模式分析
      • 5.2 未來展望
    • 6. 結論
      • 附 Java企業生態系統演進代碼示例
  • Java企業生態系統演進代碼示例
    • 主要框架演進
      • 1. 原始Java階段 (1995-1999)
      • 2. J2EE階段 (1999-2004)
      • 3. Spring框架階段 (2004-2012)
      • 4. Spring Boot階段 (2014-2018)
      • 5. Spring Cloud階段 (2015-至今)
    • 數據訪問技術演進
    • Web開發范式演進

摘要

本文系統性地分析了Java企業生態系統自1995年誕生以來的演進歷程,重點關注三條主要技術路線:整體框架演進、數據訪問技術演進以及Web開發范式演進。研究表明,Java生態系統的發展遵循了從復雜到簡化、從緊耦合到松耦合、從單體到分布式的總體趨勢。通過對各個演進階段的技術特征、架構模式和設計理念的深入分析,本文揭示了推動Java技術棧演進的核心驅動力:開發效率提升、維護成本降低以及適應不斷變化的業務需求。研究結果對理解企業軟件架構的演進規律和預測未來發展趨勢具有重要的理論和實踐意義。

關鍵詞:Java企業生態系統、框架演進、軟件架構、Spring、微服務

在這里插入圖片描述

1. 引言

Java作為一種面向對象的編程語言,自1995年誕生以來,已經發展成為企業級應用開發的主流技術。在這一演進過程中,Java生態系統經歷了從簡單到復雜再到簡化的辯證發展,形成了豐富多樣的框架、工具和最佳實踐。本文旨在從學術角度系統梳理Java企業生態系統的演進歷程,深入分析每一次技術變革背后的動因和影響,為理解軟件架構的演進規律提供理論參考。

研究表明,Java生態系統的演進可以從三個維度進行考察:整體框架演進、數據訪問技術演進以及Web開發范式演進。這三條技術路線雖各有側重,但相互影響、共同推動了Java企業應用從最初的簡單應用到當今的云原生微服務架構的轉變。

2. 整體框架演進:從原始Java到Spring Cloud

在這里插入圖片描述

2.1 原始Java階段(1995-1999)

最初的Java應用開發主要依賴于Java SE(Standard Edition)提供的基礎類庫,開發者需要編寫大量底層代碼實現業務邏輯。這一階段的特點是:

  • 缺乏統一的企業級應用開發規范
  • 應用架構高度依賴開發者個人經驗
  • 組件復用率低,維護成本高
  • 分布式計算能力有限

在此階段,開發者通常需要直接處理網絡通信、線程管理、異常處理等底層問題,導致開發效率低下,代碼質量參差不齊。

2.2 J2EE階段(1999-2004)

1999年,Sun Microsystems發布了Java 2 Enterprise Edition(J2EE),首次為企業級Java應用提供了統一的規范和標準組件。J2EE包含了多個核心組件:

  • Enterprise JavaBeans(EJB):提供分布式組件模型
  • Java Servlet:處理HTTP請求
  • JavaServer Pages(JSP):動態生成Web內容
  • Java Transaction API(JTA):管理分布式事務
  • Java Naming and Directory Interface(JNDI):提供命名和目錄服務
  • Java Message Service(JMS):實現企業消息傳遞

J2EE的出現標志著Java正式進入企業級應用開發領域。然而,隨著實踐的深入,J2EE的問題也逐漸顯現:

  • 過度設計和復雜的規范
  • EJB組件模型過于笨重
  • 配置繁瑣,依賴大型應用服務器
  • 開發周期長,學習曲線陡峭

這些問題導致了"J2EE疲勞"現象,為輕量級框架的興起創造了條件。

2.3 輕量級框架階段(2002-2006)

為了解決J2EE的復雜性問題,以Hibernate、Struts和Spring為代表的輕量級框架開始興起。這些框架的特點是:

  • 專注于解決特定領域問題
  • 簡化配置,減少樣板代碼
  • 不依賴于大型應用服務器
  • 提高開發效率和代碼可測試性

其中,Rod Johnson在2002年發表的《Expert One-on-One J2EE Design and Development》一書中提出的Spring框架,通過依賴注入(DI)和面向切面編程(AOP)等創新概念,為Java企業級應用開發帶來了革命性變化。

2.4 Spring框架階段(2004-2012)

Spring框架逐漸成為Java企業應用開發的事實標準,其核心思想是:

  • 控制反轉(IoC)容器:管理對象生命周期和依賴關系
  • 面向切面編程(AOP):分離橫切關注點
  • 聲明式事務管理:簡化事務控制
  • 統一的異常體系:簡化異常處理
  • 與其他框架的無縫集成:如Hibernate、JPA等

Spring框架的模塊化設計允許開發者根據需要選擇特定功能,極大地提高了開發靈活性。然而,隨著Spring生態系統的不斷擴展,配置的復雜性再次成為問題。

2.5 Spring Boot階段(2014-2018)

為了解決Spring框架配置復雜的問題,Pivotal團隊于2014年推出了Spring Boot。Spring Boot基于"約定優于配置"原則,提供了以下核心特性:

  • 自動配置:根據類路徑自動配置Spring應用
  • 起步依賴:簡化Maven/Gradle配置
  • 內嵌服務器:內置Tomcat、Jetty或Undertow
  • 外部化配置:支持多種配置源
  • Actuator:提供生產級監控和管理功能

Spring Boot極大地簡化了Spring應用的開發流程,減少了配置代碼,使開發者能夠更加專注于業務邏輯。

2.6 Spring Cloud階段(2015-至今)

隨著微服務架構的興起,Spring Cloud應運而生。Spring Cloud是一套基于Spring Boot的微服務開發工具,提供了:

  • 服務注冊與發現:如Eureka、Consul
  • 客戶端負載均衡:如Ribbon
  • 聲明式REST客戶端:Feign
  • 分布式配置:Spring Cloud Config
  • 斷路器:Hystrix
  • API網關:Zuul、Spring Cloud Gateway
  • 分布式追蹤:Sleuth、Zipkin

Spring Cloud為微服務架構的實現提供了完整的技術棧,使得復雜的分布式系統開發變得相對簡單,推動了Java應用從單體架構向微服務架構的轉變。

3. 數據訪問技術演進:從JDBC到Spring Data

在這里插入圖片描述

3.1 JDBC階段(1997-2002)

Java Database Connectivity(JDBC)是Java最早的數據庫訪問API,提供了與關系型數據庫交互的基礎能力。JDBC的特點是:

  • 直接操作SQL語句
  • 手動管理數據庫連接和資源釋放
  • 手動映射結果集到Java對象
  • 異常處理繁瑣

使用JDBC進行數據庫操作通常需要編寫大量樣板代碼,例如:

Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {conn = DriverManager.getConnection(URL, USER, PASSWORD);stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");stmt.setLong(1, userId);rs = stmt.executeQuery();if (rs.next()) {User user = new User();user.setId(rs.getLong("id"));user.setName(rs.getString("name"));// 更多映射...return user;}return null;
} catch (SQLException e) {throw new DataAccessException(e);
} finally {// 資源釋放代碼...
}

這種方式不僅冗長,而且容易出錯,尤其是在處理資源釋放和異常時。

3.2 DAO模式階段(2000-2005)

為了解決JDBC直接使用的問題,數據訪問對象(Data Access Object,DAO)模式開始流行。DAO模式的核心思想是:

  • 分離數據訪問邏輯和業務邏輯
  • 封裝數據庫訪問細節
  • 提供面向對象的數據訪問接口
  • 實現數據訪問的可插拔性

典型的DAO實現包括:

public interface UserDao {User findById(Long id);void save(User user);void update(User user);void delete(User user);
}public class JdbcUserDao implements UserDao {// JDBC實現...
}

DAO模式雖然提高了代碼的組織性,但并未從根本上解決JDBC使用的繁瑣問題。

3.3 ORM(Hibernate)階段(2002-2008)

對象關系映射(Object-Relational Mapping,ORM)技術的出現,特別是Hibernate框架,徹底改變了Java數據訪問的方式。ORM的核心特性包括:

  • 自動映射Java對象和數據庫表
  • 透明的持久化機制
  • 緩存機制提高性能
  • 復雜查詢支持
  • 事務管理

使用Hibernate,開發者可以通過簡單的注解或XML配置實現對象與數據庫的映射:

@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "username")private String name;// getters and setters...
}

Hibernate大大簡化了數據訪問代碼,但其配置復雜性和學習曲線仍然較高。

3.4 JPA階段(2006-2012)

為了標準化ORM技術,Java社區提出了Java Persistence API(JPA)規范。JPA提供了:

  • 統一的ORM標準
  • 供應商中立的API
  • 標準化的查詢語言(JPQL)
  • 標準化的對象生命周期管理

JPA的出現使得應用程序可以輕松切換底層ORM實現(如Hibernate、EclipseLink等),提高了代碼的可移植性。

3.5 Spring Data階段(2011-至今)

Spring Data進一步簡化了數據訪問層的開發,其核心思想是通過接口定義和約定減少樣板代碼。Spring Data的特點包括:

  • 基于接口的DAO自動實現
  • 方法名約定自動生成查詢
  • 分頁和排序支持
  • 自定義查詢注解
  • 多數據源支持
  • 非關系型數據庫支持

使用Spring Data,開發者只需定義接口,無需編寫實現類:

public interface UserRepository extends JpaRepository<User, Long> {User findByName(String name);List<User> findByAgeGreaterThan(int age);@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")List<User> findByEmailDomain(@Param("domain") String domain);
}

Spring Data極大地提高了數據訪問層的開發效率,是當前Java數據訪問技術的主流選擇。

4. Web開發范式演進:從Servlet/JSP到前后端分離

在這里插入圖片描述

4.1 Servlet/JSP階段(1997-2003)

Java Web開發最初基于Servlet和JSP技術:

  • Servlet:處理HTTP請求和響應
  • JSP:混合HTML和Java代碼生成動態內容
  • JavaBeans:封裝數據

這一階段的Web應用通常采用Model 1架構,即JSP頁面直接處理請求并生成響應。這種架構在簡單應用中表現良好,但隨著應用復雜性增加,代碼維護變得困難。

4.2 Struts階段(2000-2006)

Apache Struts框架引入了Model-View-Controller(MVC)模式,將Web應用分為三個部分:

  • Model:業務邏輯和數據訪問
  • View:表現層,通常是JSP
  • Controller:處理請求,協調Model和View

Struts的核心組件包括:

  • ActionServlet:中央控制器
  • ActionForm:封裝表單數據
  • Action:處理具體業務邏輯
  • struts-config.xml:配置文件

Struts改進了Web應用的架構,但其配置繁瑣且缺乏靈活性。

4.3 JSF階段(2004-2010)

JavaServer Faces(JSF)是Java EE的標準Web框架,引入了組件化開發模型:

  • UI組件模型:預定義的可重用組件
  • 導航模型:聲明式頁面導航
  • 托管Bean:后臺Java對象
  • 事件驅動模型:類似桌面應用開發

JSF簡化了復雜UI的開發,但其生命周期復雜,性能問題明顯,逐漸被更輕量級的框架所取代。

4.4 Spring MVC階段(2005-2015)

Spring MVC是Spring框架的Web模塊,提供了一種輕量級的MVC實現:

  • DispatcherServlet:中央控制器
  • 基于注解的控制器
  • 靈活的視圖解析
  • 數據綁定和驗證
  • 與Spring生態系統無縫集成

Spring MVC的簡潔性和靈活性使其成為長期流行的Web框架:

@Controller
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public String getUser(@PathVariable Long id, Model model) {model.addAttribute("user", userService.findById(id));return "userDetails";}
}

4.5 RESTful API階段(2010-2017)

隨著移動應用和單頁應用(SPA)的興起,RESTful API逐漸成為主流的Web開發模式:

  • 資源導向設計
  • 標準HTTP方法語義(GET、POST、PUT、DELETE)
  • 無狀態通信
  • JSON/XML數據交換
  • 超媒體鏈接(HATEOAS)

Spring MVC和后來的Spring Boot都提供了優秀的RESTful API支持:

@RestController
@RequestMapping("/api/users")
public class UserApiController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User getUser(@PathVariable Long id) {return userService.findById(id);}@PostMapping@ResponseStatus(HttpStatus.CREATED)public User createUser(@RequestBody User user) {return userService.save(user);}
}

4.6 前后端分離階段(2015-至今)

最新的Web開發范式是完全的前后端分離:

  • 后端:專注于API提供和業務邏輯
  • 前端:使用JavaScript框架(React、Angular、Vue.js)構建客戶端應用
  • 通過API進行數據交換
  • 各自獨立開發、測試和部署

這種架構帶來了多種優勢:

  • 關注點分離,專業分工
  • 提高開發效率
  • 更好的用戶體驗
  • 多端復用后端API(Web、移動、桌面)

5. 演進模式分析與展望

5.1 演進模式分析

通過對Java企業生態系統演進的系統分析,可以發現以下關鍵模式:

  1. 復雜性循環:從簡單到復雜再到簡化的循環演進
  2. 關注點分離:持續細化和分離系統關注點
  3. 標準化與創新:標準化與創新相互促進
  4. 開發效率驅動:開發效率始終是核心驅動力
  5. 適應性演進:對業務需求變化的持續適應

5.2 未來展望

Java企業生態系統的未來發展可能包括:

  1. 云原生技術深化:如GraalVM、Quarkus等
  2. 響應式編程模型普及:如Project Reactor、RxJava
  3. 函數式編程范式融合:函數式特性在企業應用中的應用
  4. 低代碼/無代碼平臺興起:降低開發門檻
  5. AI輔助開發:人工智能輔助編碼和測試

6. 結論

本文系統梳理了Java企業生態系統在框架、數據訪問和Web開發三個維度的演進歷程。研究表明,Java生態系統的發展遵循了從復雜到簡化、從緊耦合到松耦合、從單體到分布式的總體趨勢。這一演進過程不僅反映了技術本身的發展,也體現了軟件工程理念的進步,對理解企業軟件架構的演進規律具有重要的理論和實踐意義。

Java企業生態系統的成功在于其持續創新與適應能力,未來仍將繼續演進以應對新的技術挑戰和業務需求。

附 Java企業生態系統演進代碼示例

一套簡單明了的代碼示例,展示了Java企業應用從最早期到現代云原生架構的演變過程。

Java企業生態系統演進代碼示例

這些代碼示例覆蓋了六大關鍵演進階段和三條主要技術路線:

主要框架演進

1. 原始Java階段 (1995-1999)

// 使用原始JDBC連接數據庫的例子
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;try {// 手動加載JDBC驅動Class.forName("com.mysql.jdbc.Driver");// 手動創建數據庫連接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");// 創建并執行SQL語句stmt = conn.createStatement();rs = stmt.executeQuery("SELECT * FROM users");// 手動處理結果集while (rs.next()) {System.out.println("User: " + rs.getString("name"));}
} catch (Exception e) {e.printStackTrace();
} finally {// 手動關閉所有資源...
}

2. J2EE階段 (1999-2004)

展示了復雜的EJB組件模型,需要定義多個接口和實現類:

// 遠程接口
public interface User extends EJBObject {String getName() throws RemoteException;void setName(String name) throws RemoteException;
}// Bean實現類 - 必須實現多個生命周期方法
public class UserBean implements EntityBean {private EntityContext context;private Long id;private String name;// 必須實現EntityBean的所有方法public void setEntityContext(EntityContext context) { this.context = context; }public void unsetEntityContext() { this.context = null; }public void ejbActivate() {}public void ejbPassivate() {}// ...更多方法...
}

3. Spring框架階段 (2004-2012)

展示了注解配置和依賴注入:

@Service
public class UserServiceImpl implements UserService {private final UserDao userDao;@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Override@Transactional(readOnly = true)public User getUser(Long id) {return userDao.findById(id);}
}

4. Spring Boot階段 (2014-2018)

展示自動配置和簡化開發:

@SpringBootApplication
public class UserManagementApplication {public static void main(String[] args) {SpringApplication.run(UserManagementApplication.class, args);}
}// 自動配置的JPA Repository - 無需實現
@Repository
public interface UserRepository extends JpaRepository<User, Long> {List<User> findByName(String name);
}

5. Spring Cloud階段 (2015-至今)

微服務架構示例:

// 微服務注冊
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}// 服務間通信
@FeignClient("order-service")
public interface OrderClient {@GetMapping("/api/orders/user/{userId}")List<Order> getOrdersByUser(@PathVariable("userId") Long userId);
}

數據訪問技術演進

從直接JDBC、DAO模式、Hibernate、JPA到Spring Data,展示了數據訪問層的簡化過程。

Web開發范式演進

從Servlet/JSP的直接操作,到Struts、JSF、Spring MVC,再到RESTful API和前后端分離架構。

這些代碼示例清晰展示了Java企業生態系統如何逐步演進,從復雜的手動配置到約定優于配置的簡化開發模式,從單體應用到分布式微服務架構。每一次演進都致力于提高開發效率、降低維護成本,并使系統更加靈活和可擴展。

// Java企業生態系統演進代碼示例/*** 1. 原始Java階段 (1995-1999)* 特點:直接使用Java SE API,手動處理底層細節*/// 使用原始JDBC連接數據庫的例子
import java.sql.*;public class OriginalJavaExample {public static void main(String[] args) {Connection conn = null;Statement stmt = null;ResultSet rs = null;try {// 手動加載JDBC驅動Class.forName("com.mysql.jdbc.Driver");// 手動創建數據庫連接conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");// 創建并執行SQL語句stmt = conn.createStatement();rs = stmt.executeQuery("SELECT * FROM users");// 手動處理結果集while (rs.next()) {System.out.println("User: " + rs.getString("name"));}} catch (Exception e) {e.printStackTrace();} finally {// 手動關閉所有資源try {if (rs != null) rs.close();if (stmt != null) stmt.close();if (conn != null) conn.close();} catch (SQLException e) {e.printStackTrace();}}}
}/*** 2. J2EE階段 (1999-2004)* 特點:EJB組件模型,復雜的配置和依賴*/// EJB 2.x示例 - 需要定義多個接口和實現類
// Home接口
public interface UserHome extends EJBHome {User create() throws CreateException, RemoteException;User findByPrimaryKey(Long id) throws FinderException, RemoteException;
}// 遠程接口
public interface User extends EJBObject {String getName() throws RemoteException;void setName(String name) throws RemoteException;
}// Bean實現類
public class UserBean implements EntityBean {private EntityContext context;private Long id;private String name;// 必須實現EntityBean的所有方法public void setEntityContext(EntityContext context) { this.context = context; }public void unsetEntityContext() { this.context = null; }public void ejbActivate() {}public void ejbPassivate() {}public void ejbLoad() {}public void ejbStore() {}public void ejbRemove() {}public Long ejbCreate() { return null; }public void ejbPostCreate() {}// 業務方法public String getName() { return name; }public void setName(String name) { this.name = name; }
}// 客戶端使用代碼
try {InitialContext ctx = new InitialContext();UserHome home = (UserHome) ctx.lookup("java:comp/env/ejb/User");User user = home.create();user.setName("John");
} catch (Exception e) {e.printStackTrace();
}/*** 3. 輕量級框架階段 (2002-2006)* 特點:簡化配置,POJO編程模型*/// Spring 1.x 示例 - 依賴注入// POJO類
public class UserService {private UserDao userDao;// setter注入public void setUserDao(UserDao userDao) {this.userDao = userDao;}public User findUser(Long id) {return userDao.findById(id);}
}// XML配置
/*
<beans><bean id="userDao" class="com.example.UserDaoImpl" /><bean id="userService" class="com.example.UserService"><property name="userDao" ref="userDao" /></bean>
</beans>
*/// Hibernate示例
public class User {private Long id;private String name;// getters and setters
}/*
<!-- Hibernate映射文件 user.hbm.xml -->
<hibernate-mapping><class name="com.example.User" table="USERS"><id name="id" column="ID"><generator class="native"/></id><property name="name" column="NAME"/></class>
</hibernate-mapping>
*//*** 4. Spring框架階段 (2004-2012)* 特點:注解配置,AOP,綜合解決方案*/// Spring 2.5+ 注解示例
@Repository
public class UserDaoImpl implements UserDao {@Overridepublic User findById(Long id) {// 實現查詢邏輯return new User(id, "User " + id);}
}@Service
public class UserServiceImpl implements UserService {private final UserDao userDao;@Autowiredpublic UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Override@Transactional(readOnly = true)public User getUser(Long id) {return userDao.findById(id);}
}// Spring MVC控制器
@Controller
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@RequestMapping("/{id}")public String getUser(@PathVariable Long id, Model model) {model.addAttribute("user", userService.getUser(id));return "userDetails";}
}/*** 5. Spring Boot階段 (2014-2018)* 特點:自動配置,起步依賴,內嵌服務器*/// 只需幾個注解即可創建完整應用
@SpringBootApplication
public class UserManagementApplication {public static void main(String[] args) {SpringApplication.run(UserManagementApplication.class, args);}
}// 自動配置的JPA Repository
@Repository
public interface UserRepository extends JpaRepository<User, Long> {// 無需實現,Spring Data自動提供實現List<User> findByName(String name);@Query("SELECT u FROM User u WHERE u.email LIKE %:domain")List<User> findByEmailDomain(@Param("domain") String domain);
}// RESTful API控制器
@RestController
@RequestMapping("/api/users")
public class UserApiController {@Autowiredprivate UserRepository userRepository;@GetMappingpublic List<User> getAllUsers() {return userRepository.findAll();}@GetMapping("/{id}")public ResponseEntity<User> getUserById(@PathVariable Long id) {return userRepository.findById(id).map(ResponseEntity::ok).orElse(ResponseEntity.notFound().build());}@PostMappingpublic User createUser(@RequestBody User user) {return userRepository.save(user);}
}// 簡化的application.properties
/*
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=user
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
*//*** 6. Spring Cloud階段 (2015-至今)* 特點:微服務架構,分布式系統支持*/// 服務注冊 - Eureka服務端
@SpringBootApplication
@EnableEurekaServer
public class ServiceRegistryApplication {public static void main(String[] args) {SpringApplication.run(ServiceRegistryApplication.class, args);}
}// 微服務 - 用戶服務
@SpringBootApplication
@EnableEurekaClient
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}// 服務間通信 - Feign客戶端
@FeignClient("order-service")
public interface OrderClient {@GetMapping("/api/orders/user/{userId}")List<Order> getOrdersByUser(@PathVariable("userId") Long userId);
}// 在用戶服務中使用訂單服務
@Service
public class UserAccountService {@Autowiredprivate UserRepository userRepository;@Autowiredprivate OrderClient orderClient;public UserAccountDetails getUserDetails(Long userId) {User user = userRepository.findById(userId).orElseThrow();List<Order> orders = orderClient.getOrdersByUser(userId);return new UserAccountDetails(user, orders);}
}// API網關配置
/*
spring:cloud:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/users/**- id: order-serviceuri: lb://order-servicepredicates:- Path=/orders/**
*//*** 數據訪問技術演進示例*/// 1. JDBC直接訪問
public User findUserById(long id) {Connection conn = null;PreparedStatement stmt = null;ResultSet rs = null;try {conn = DriverManager.getConnection(DB_URL, USER, PASS);stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");stmt.setLong(1, id);rs = stmt.executeQuery();if (rs.next()) {User user = new User();user.setId(rs.getLong("id"));user.setName(rs.getString("name"));return user;}return null;} catch (SQLException e) {throw new RuntimeException(e);} finally {// 關閉資源}
}// 2. DAO模式
public interface UserDao {User findById(long id);void save(User user);void update(User user);void delete(User user);
}public class JdbcUserDao implements UserDao {@Overridepublic User findById(long id) {// JDBC實現}// 其他方法實現
}// 3. Hibernate ORM
public class HibernateUserDao implements UserDao {private SessionFactory sessionFactory;@Overridepublic User findById(long id) {Session session = sessionFactory.getCurrentSession();return (User) session.get(User.class, id);}@Overridepublic void save(User user) {Session session = sessionFactory.getCurrentSession();session.save(user);}// 其他方法實現
}// 4. JPA
@Entity
@Table(name = "users")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "name")private String name;// getters and setters
}public class JpaUserDao implements UserDao {@PersistenceContextprivate EntityManager entityManager;@Overridepublic User findById(long id) {return entityManager.find(User.class, id);}@Overridepublic void save(User user) {entityManager.persist(user);}// 其他方法實現
}// 5. Spring Data
public interface UserRepository extends JpaRepository<User, Long> {// 自動生成實現List<User> findByNameContaining(String namePart);@Query("SELECT u FROM User u WHERE u.active = true")List<User> findActiveUsers();
}// 使用Spring Data
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public List<User> findActiveUsersWithName(String name) {return userRepository.findByNameContaining(name).stream().filter(User::isActive).collect(Collectors.toList());}
}/*** Web開發演進示例*/// 1. Servlet/JSP
public class UserServlet extends HttpServlet {private UserDao userDao = new JdbcUserDao();@Overrideprotected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String idStr = req.getParameter("id");long id = Long.parseLong(idStr);User user = userDao.findById(id);req.setAttribute("user", user);RequestDispatcher dispatcher = req.getRequestDispatcher("/user.jsp");dispatcher.forward(req, resp);}
}// JSP頁面
/*
<html>
<body><h1>User Details</h1><p>ID: <%= ((User)request.getAttribute("user")).getId() %></p><p>Name: <%= ((User)request.getAttribute("user")).getName() %></p>
</body>
</html>
*/// 2. Struts
public class UserAction extends Action {private UserDao userDao = new JdbcUserDao();@Overridepublic ActionForward execute(ActionMapping mapping, ActionForm form,HttpServletRequest request, HttpServletResponse response) throws Exception {UserForm userForm = (UserForm) form;long id = userForm.getId();User user = userDao.findById(id);userForm.setName(user.getName());return mapping.findForward("success");}
}// 3. JSF
@ManagedBean
@RequestScoped
public class UserBean {@EJBprivate UserService userService;private long id;private String name;public String loadUser() {User user = userService.findById(id);this.name = user.getName();return "userDetails";}// getters and setters
}// JSF頁面
/*
<h:form><h:inputText value="#{userBean.id}" /><h:commandButton value="Load" action="#{userBean.loadUser}" /><h:outputText value="#{userBean.name}" />
</h:form>
*/// 4. Spring MVC
@Controller
@RequestMapping("/users")
public class UserController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public String getUser(@PathVariable Long id, Model model) {User user = userService.findById(id);model.addAttribute("user", user);return "userDetails";}@PostMappingpublic String createUser(@ModelAttribute User user) {userService.save(user);return "redirect:/users/" + user.getId();}
}// 5. RESTful API
@RestController
@RequestMapping("/api/users")
public class UserRestController {@Autowiredprivate UserService userService;@GetMapping("/{id}")public User getUser(@PathVariable Long id) {return userService.findById(id);}@PostMapping@ResponseStatus(HttpStatus.CREATED)public User createUser(@RequestBody User user) {return userService.save(user);}@PutMapping("/{id}")public User updateUser(@PathVariable Long id, @RequestBody User user) {user.setId(id);return userService.update(user);}@DeleteMapping("/{id}")@ResponseStatus(HttpStatus.NO_CONTENT)public void deleteUser(@PathVariable Long id) {userService.delete(id);}
}// 6. 前后端分離
// 后端: Spring Boot RESTful API (同上)// 前端: React組件
/*
import React, { useState, useEffect } from 'react';
import axios from 'axios';function UserList() {const [users, setUsers] = useState([]);useEffect(() => {axios.get('/api/users').then(response => {setUsers(response.data);}).catch(error => console.error(error));}, []);return (<div><h1>Users</h1><ul>{users.map(user => (<li key={user.id}>{user.name}</li>))}</ul></div>);
}export default UserList;
*/

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/70705.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/70705.shtml
英文地址,請注明出處:http://en.pswp.cn/web/70705.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

kicad中R樹的使用

在 KiCad 中&#xff0c;使用 R樹&#xff08;R-tree&#xff09;進行空間索引和加速查詢通常不在用戶層面直接操作&#xff0c;而是作為工具的一部分用于優化電路板設計的性能&#xff0c;尤其在布局、碰撞檢測、設計規則檢查&#xff08;DRC&#xff09;以及元件搜索等方面。…

org.springframework.boot不存在的其中一個解決辦法

最近做項目的時候發現問題&#xff0c;改了幾次pom.xml文件之后突然發現項目中的注解全部爆紅。 可以嘗試點擊左上角的循環小圖標&#xff0c;同步所有maven項目。 建議順便檢查一下Project Structure中的SDK和Language Level是否對應&#xff0c;否則可能報類似&#xff1a;“…

C語言實現通訊錄項目

一、通訊錄功能 實現一個可以存放100個人的信息的通訊錄&#xff08;這里采用靜態版本&#xff09;&#xff0c;每個人的信息有姓名、性別、年齡、電話、地址等。 通訊錄可以執行的操作有添加聯系人信息、刪除指定聯系人、查找指定聯系人信息、修改指定聯系人信息、顯示聯系人信…

HO3D_v3(handposeX-json 格式)數據集-release >> DataBall

注意&#xff1a; 1)為了方便使用&#xff0c;按照 handposeX json 自定義格式存儲 2)使用常見依賴庫進行調用,降低數據集使用難度。 3)部分數據集獲取請加入&#xff1a;DataBall-X數據球(free) 4)完整數據集獲取請加入&#xff1a;DataBall-X數據球(vip) HO3D 數據集官方…

Java線程池入門04

1. 提交任務的兩種方式 executorsubmit 2. executor executor位于Executor接口中 public interface Executor {void executor(Runnable command); }executor提交的是無返回值的任務 下面是一個具體的例子 package LearnThreadPool; import java.util.concurrent.ExecutorSe…

2025-02-26 學習記錄--C/C++-C語言 整數格式說明符

合抱之木&#xff0c;生于毫末&#xff1b;九層之臺&#xff0c;起于累土&#xff1b;千里之行&#xff0c;始于足下。&#x1f4aa;&#x1f3fb; C語言 整數格式說明符 【例如 】&#x1f380; &#xff1a;在 C 語言中&#xff0c;%ld 是 printf 或 scanf 等格式化輸入輸出函…

【QT 一 | 信號和槽】

Qt5基本模塊 Qt Creator 中的快捷鍵 ? 注釋&#xff1a;ctrl / ? 運?&#xff1a;ctrl R ? 編譯&#xff1a;ctrl B ? 字體縮放&#xff1a;ctrl 鼠標滑輪 ? 查找&#xff1a;ctrl F ? 整行移動&#xff1a;ctrl shift ?/? ? 幫助?檔&#xff1a;F1 ? 自動…

集成學習方法之隨機森林

隨機森林是一種集成學習算法&#xff0c;它基于決策樹模型&#xff0c;通過構建多個決策樹并將它們的預測結果進行組合&#xff0c;以提高模型的準確性和穩定性。以下是隨機森林的詳細介紹&#xff1a; 原理 隨機森林通過從原始訓練數據中有放回地隨機抽樣&#xff0c;生成多…

react 中,使用antd layout布局中的sider 做sider的展開和收起功能

一 話不多說&#xff0c;先展示效果&#xff1a; 展開時&#xff1a; 收起時&#xff1a; 二、實現代碼如下 react 文件 import React, {useState} from react; import {Layout} from antd; import styles from "./index.module.less"; // 這個是樣式文件&#…

【Java 基礎】-- Java 接口中的 @Public 和 @FunctionalInterface 注解詳解

目錄 Java 接口中的 Public 和 FunctionalInterface 注解詳解 1. 概述 2. Public 注解的作用 3. Public 注解的使用 3.1 基本使用方式 3.2 應用于類和方法 4. FunctionalInterface 注解的作用 4.1 主要作用 4.2 FunctionalInterface 使用示例 4.3 允許默認方法 5. Pu…

go語言環境下載與配置(Windows)

下載 Go下載 - Go語言中文網 - Golang中文社區 建議在D盤中創建文件夾安裝到 D 盤 &#xff0c;方便進行管理&#xff0c;然后進行傻瓜式安裝。 安裝 驗證安裝 go version 安裝成功 配置環境變量 winE --> 右擊此電腦 --> 選擇屬性 --> 高級系統設置 --> 點擊…

nss刷題5(misc)

[HUBUCTF 2022 新生賽]最簡單的misc 打開后是一張圖片&#xff0c;沒有其他東西&#xff0c;分離不出來&#xff0c;看看lsb&#xff0c;紅綠藍都是0&#xff0c;看到頭是png&#xff0c;重新保存為png&#xff0c;得到一張二維碼 掃碼得到flag [羊城杯 2021]簽到題 是個動圖…

OkHttp、Retrofit、RxJava:一文講清楚

一、okHttp的同步和異步請求 Call 是 OkHttp 的核心接口&#xff0c;代表一個已準備好執行的 HTTP 請求。它支持 同步 和 異步 兩種模式&#xff1a; enqueue——>okHttp異步 OkHttpClient client new OkHttpClient();Request request new Request.Builder().url("…

Redis分布式緩存面試題

為什么使用分布式緩存&#xff1f; 1. 提升性能 降低延遲&#xff1a;將數據緩存在離應用更近的地方&#xff0c;減少數據訪問時間。減輕數據庫壓力&#xff1a;緩存頻繁訪問的數據&#xff0c;減少對后端數據庫的請求&#xff0c;提升系統響應速度。 2. 擴展性 水平擴展&a…

基于阿里云PAI平臺快速部署DeepSeek大模型實戰指南

一、DeepSeek大模型&#xff1a;企業級AI應用的新標桿 1.1 為什么選擇DeepSeek&#xff1f; 近期&#xff0c;DeepSeek系列模型憑借其接近GPT-4的性能和開源策略&#xff0c;成為全球開發者關注的焦點。在多項國際評測中&#xff0c;DeepSeek-R1模型在推理能力、多語言支持和…

C++---了解STL

上節學習了模板&#xff0c;那么就得談到C的標準模板庫STL。 C98&#xff1a;以模板方式重寫了C標準庫&#xff0c;引入了STL(標準模板庫)。 1.概念 STL(Standard template Libarary)標準模板庫&#xff1a;是C標準庫的重要組成部分&#xff0c;不僅是一個可復用的組件庫&am…

分享幾款比較常用的接口測試工具

首先&#xff0c;什么是接口呢&#xff1f; 接口一般來說有兩種&#xff0c;一種是程序內部的接口&#xff0c;一種是系統對外的接口。 系統對外的接口&#xff1a;比如你要從別的網站或服務器上獲取資源或信息&#xff0c;別人肯定不會把數據庫共享給你&#xff0c;他只能給你…

Qt layout

文章目錄 Qt layout**關鍵機制****驗證示例****常見誤區****最佳實踐****總結**關鍵點總結&#xff1a;示例代碼說明&#xff1a;結論&#xff1a; Qt layout 在 Qt 中&#xff0c;當調用 widget->setLayout(layout) 時&#xff0c;layout 的父對象會被自動設置為該 widget…

flutter: table calendar筆記

pub dev&#xff1a;table_calendar 3.2.0 我來詳細解釋 TableCalendar 是如何根據不同的 CalendarFormat 來顯示界面的。主要邏輯在 CalendarCore 中實現。 核心邏輯分為以下幾個部分&#xff1a; 頁面數量計算 - _getPageCount 方法根據不同格式計算總頁數&#xff1a; in…

【C++】各個版本新的特性和改進

C 語言自從其誕生以來&#xff0c;經歷了多個版本的更新&#xff0c;每個版本都引入了新的特性和改進&#xff0c;目的是提升語言的表達能力、性能、安全性以及開發效率。下面是各個主要版本&#xff08;從 C98 到 C20&#xff09;的一些關鍵特性。 C98 (1998年) ISO C 標準化…