【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.rhkb.cn/news/24683.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内容中台的企业CMS架构是什么?

企业CMS模块化架构 现代企业内容管理系统的核心在于模块化架构设计&#xff0c;通过解耦内容生产、存储、发布等环节构建灵活的技术栈。动态/静态发布引擎整合技术使系统既能处理实时更新的产品文档&#xff0c;也能生成高并发的营销落地页&#xff0c;配合版本控制机制确保内…

Binder通信协议

目录 一,整体架构 二,Binder通信协议 三&#xff0c;binder驱动返回协议 四&#xff0c;请求binder驱动协议 一,整体架构 二,Binder通信协议 三&#xff0c;binder驱动返回协议 binder_driver_return_protocol共包含18个命令&#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"; // 这个是样式文件&#…

神经网络 - 激活函数(Sigmoid 型函数)

激活函数在神经元中非常重要的。为了增强网络的表示能力和学习能力&#xff0c;激活函数需要具备以下几点性质: (1) 连续并可导(允许少数点上不可导)的非线性函数。可导的激活函数可以直接利用数值优化的方法来学习网络参数. (2) 激活函数及其导函数要尽可能的简单&#xff0…

供应链管理系统--升鲜宝门店收银系统功能解析,登录、主界面、会员 UI 设计图(一)

供应链管理系统--升鲜宝门店收银系统功能解析&#xff0c;登录、主界面 会员 UI 设计图&#xff08;一&#xff09;

从零开始的网站搭建(以照片/文本/视频信息通信网站为例)

本文面向已经有一些编程基础&#xff08;会至少一门编程语言&#xff0c;比如python&#xff09;&#xff0c;但是没有搭建过web应用的人群&#xff0c;会写得尽量细致。重点介绍流程和部署云端的步骤&#xff0c;具体javascript代码怎么写之类的&#xff0c;这里不会涉及。 搭…

三轴加速度推算姿态角的方法,理论分析和MATLAB例程

三轴加速度推算三轴姿态的方法与MATLAB代码实现 文章目录 基本原理与方法概述静态姿态解算(仅俯仰角与横滚角)扩展(融合陀螺仪与加速度计)MATLAB代码 例程四元数动态姿态解算(融合加速度与陀螺仪)注意事项与扩展基本原理与方法概述 三轴加速度计通过测量重力分量在载体坐…

2025最新Flask学习笔记(对照Django做解析)

前言&#xff1a;如果还没学Django的同学&#xff0c;可以看Django 教程 | 菜鸟教程&#xff0c;也可以忽略下文所提及的Django内容&#xff1b;另外&#xff0c;由于我们接手的项目大多都是前后端分离的项目&#xff0c;所以本文会跳过对模板的介绍&#xff0c;感兴趣的朋友可…

HTML第二节

一.列表 1.列表的简介 2.无序列表 注&#xff1a;1.ul里面只能放li&#xff0c;不能放标题和段落标签 2.li里面可以放标题和段落等内容 3.有序列表 4.定义列表 注&#xff1a;要实现上图的效果需要CSS 二.表格 1.表格介绍 注&#xff1a;1.th有额外的效果&#xff0c;可以…

SpringBoot——生成Excel文件

在Springboot以及其他的一些项目中&#xff0c;或许我们可能需要将数据查询出来进行生成Excel文件进行数据的展示&#xff0c;或者用于进行邮箱发送进行附件添加 依赖引入 此处demo使用maven依赖进行使用 <dependency><groupId>org.apache.poi</groupId>&…

【Akashic Records】《命若琴弦》

博客主页&#xff1a; [小ᶻ☡꙳ᵃⁱᵍᶜ꙳] 本文专栏: Akashic Records 文章目录 &#x1f4af;观后感命运的无情与生命的坚持希望的火种与人生的意义虚无与活在当下生死的辩证与享受当下结语 &#x1f4af;观后感 命若琴弦 生命的意义本不在向外的寻取&#xff0c;而在…

C#调用CANoeCLRAdapter.dll文章(一)

一、引言 CANoe 是 Vector 公司开发的一款广泛应用于汽车电子开发、测试和分析的工具。CANoe CLR Adapter 允许开发者使用 C# 等.NET 语言来扩展 CANoe 的功能&#xff0c;实现更灵活、强大的自动化测试和数据处理。本指南将详细介绍如何基于 C# 进行 CANoe CLR Adapter 的开发…

运维和AI的邂逅: 让你的 ssh/terminal 智能化

运维同学很多工作其实就是在命令行里操作服务器&#xff0c;尽管目前有很多可视化的工具&#xff0c;但是命令行(ssh 登录)依然不可或缺&#xff0c;甚至依然还占据着主要工作。这意味着运维同学需要掌握大量和服务器操作系统以及shell相关的知识&#xff0c;记住大量的命令。 …

CMake小结2(PICO为例)

1 前言 之前写过一篇cmake&#xff0c;不过很简单&#xff1a;CMake小结_cmake ${sources}-CSDN博客 构建系统现在真的太多了&#xff0c;完全学不过来的感觉&#xff0c;meson&#xff0c;gardle&#xff0c;buildroot&#xff0c; Maven。。。我是真的有点放弃治疗了。之前…

使用OpenCV实现帧间变化检测:基于轮廓的动态区域标注

在计算机视觉中&#xff0c;帧间差异检测&#xff08;frame differencing&#xff09;是一种常用的技术&#xff0c;用于检测视频流中的动态变化区域。这种方法尤其适用于监控、运动分析、目标追踪等场景。在这篇博客中&#xff0c;我们将通过分析一个基于OpenCV的简单帧间差异…

机器学习01

机器学习的基本过程如下&#xff1a; 1.数据获取 2.数据划分 3.特征提取 4.模型选择与训练 5.模型评估 6.模型调优 一、特征工程&#xff08;重点&#xff09; 0. 特征工程步骤为&#xff1a; 特征提取(如果不是像dataframe那样的数据&#xff0c;要进行特征提取&#…

每日Attention学习24——Strip Convolution Block

模块出处 [TIP 21] [link] CoANet: Connectivity Attention Network for Road Extraction From Satellite Imagery 模块名称 Strip Convolution Block (SCB) 模块作用 多方向条形特征提取 模块结构 模块特点 类PSP设计&#xff0c;采用四个并行分支提取不同维度的信息相比于…

用FileZilla Server 1.9.4给Windows Server 2025搭建FTP服务端

FileZilla Server 是一款免费的开源 FTP 和 FTPS 服务器软件&#xff0c;分为服务器版和客户端版。服务器版原本只支持Windows操作系统&#xff0c;比如笔者曾长期使用过0.9.60版&#xff0c;那时候就只支持Windows操作系统。当时我们生产环境对FTP稳定性要求较高&#xff0c;比…

es-head(es库-谷歌浏览器插件)

1.下载es-head插件压缩包&#xff0c;并解压缩 2.谷歌浏览器添加插件 3.使用

健康检查、k8s探针、Grails+Liquibase框架/health 404 Not Found排查及解决

概述 健康检查对于一个pod而言&#xff0c;其重要性不言而喻。 k8s通过探针来实现健康检查。 探针 k8s提供三种探针&#xff1a; 存活探针&#xff1a;livenessProbe就绪探针&#xff1a;readinessProbe启动探针&#xff1a;startupProbe 存活探针 存活探针决定何时重启…