【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.mzph.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 标准化…