当前位置: 首页 > news >正文

JavaEE Spring框架的概述与对比无框架下的优势

 Spring 是一个开放源代码的设计层面框架,它解决的是业务逻辑层和其他各层的 松耦合问题,因此它将面向接口的编程思想贯穿整个系统应用。

我们一般说 Spring 框架指的都是 Spring Framework,它是很多模块的集合,使用这些模块可以很方便地协助我们进行开发。这些模块是:核心容器、数据访问/集成,、Web、AOP(面向切面编程)、工具、消息和测试模块。

1.Spring的特征与特性

1.1 Spring 官网(Spring | Home)列出的 Spring 的 6 个特征:

  • 核心技术 :依赖注入(DI),AOP,事件(events),资源,i18n,验证,数据绑定,类型转换,SpEL。
  • 测试 :模拟对象,TestContext框架,Spring MVC 测试,WebTestClient。
  • 数据访问 :事务,DAO支持,JDBC,ORM,编组XML。
  • Web支持 : Spring MVC和Spring WebFlux Web框架。
  • 集成 :远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
  • 语言 :Kotlin,Groovy,动态语言。

1.2 Spring的核心特性 对比无框架的优势

1.2.1 IoC(控制反转)与 DI(依赖注入):通过 IoC 容器管理对象的创建和依赖关系,减少代码耦合。

Spring 框架下无框架下
对象创建IoC 容器(如 ApplicationContext)自动创建对象,开发者只需定义对象规则(如类、注解),无需手动new需手动通过new关键字创建对象,对象的生命周期由开发者手动控制(创建、销毁)。
依赖关系处理通过 DI(构造器注入、setter 注入等)自动维护依赖,依赖关系通过配置(注解 / XML)声明,无需硬编码。例如:@Autowired private UserService userService即可获取依赖,无需在代码中new UserService()依赖关系硬编码在业务代码中,例如:UserService userService = new UserServiceImpl(); 若UserService的实现类变更,所有引用处都需修改,耦合度极高。

无框架实现:

// 1. 定义接口
public interface UserService {void createUser(String username);
}// 2. 实现类
public class UserServiceImpl implements UserService {private UserDao userDao;  // 依赖UserDaopublic UserServiceImpl() {// 硬编码创建依赖对象this.userDao = new UserDaoImpl(); }@Overridepublic void createUser(String username) {// 业务逻辑 + 依赖调用System.out.println("Creating user: " + username);userDao.save(username);}
}// 3. 客户端调用
public class Client {public static void main(String[] args) {// 手动创建对象及依赖链UserService service = new UserServiceImpl();service.createUser("test");}
}

问题

  • UserServiceImplUserDaoImpl强绑定,若需替换UserDao实现(如改为测试用的MockUserDao),必须修改UserServiceImpl代码。

Spring 框架实现(依赖注入):

// 1. 定义接口
public interface UserService {void createUser(String username);
}// 2. 实现类(通过@Service自动注册为Bean)
@Service
public class UserServiceImpl implements UserService {private final UserDao userDao;  // 依赖UserDao// 构造器注入(@Autowired可省略)public UserServiceImpl(UserDao userDao) {this.userDao = userDao;}@Overridepublic void createUser(String username) {System.out.println("Creating user: " + username);userDao.save(username);}
}// 3. 配置类(或通过@ComponentScan自动扫描)
@Configuration
@ComponentScan(basePackages = "com.example.service")
public class AppConfig {@Beanpublic UserDao userDao() {return new UserDaoImpl();  // 配置依赖实现}
}// 4. 客户端调用
public class Client {public static void main(String[] args) {// 通过Spring容器获取Bean,无需手动创建ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);UserService service = context.getBean(UserService.class);service.createUser("test");}
}

优势

  • UserServiceImpl不负责创建UserDao,依赖关系由 Spring 容器管理,可通过配置动态替换实现(如测试时注入MockUserDao)。
  • 对象创建逻辑集中在配置类,客户端只需从容器获取 Bean,降低耦合。

1.2.2 AOP(面向切面编程):允许分离横切关注点(如日志、事务管理),提高代码模块化。

Spring 框架下无框架下
横切逻辑实现通过 AOP 将日志、权限校验、异常处理等横切逻辑与业务逻辑分离,例如:用@Aspect定义切面,通过@Before/@After指定拦截规则,无需侵入业务代码。横切逻辑需嵌入业务代码中,每个业务方法开头手动写日志打印、权限判断,导致代码冗余(重复代码多)、业务逻辑与非业务逻辑混杂。
维护成本横切逻辑集中管理,修改时只需调整切面代码(如日志格式变更),无需修改所有业务方法。横切逻辑分散在成百上千个业务方法中,修改时需逐个调整,极易遗漏,维护成本极高。

无框架下的问题代码:

public class UserServiceImpl implements UserService {@Overridepublic void createUser(String username) {// 1. 重复的前置日志(横切逻辑)System.out.println("[INFO] Start creating user: " + username);long startTime = System.currentTimeMillis();// 2. 核心业务逻辑try {System.out.println("Creating user in database...");Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}// 3. 重复的后置日志(横切逻辑)long endTime = System.currentTimeMillis();System.out.println("[INFO] User created. Time elapsed: " + (endTime - startTime) + "ms");}
}

问题:横切逻辑与业务逻辑耦合,导致代码冗余、难以维护

Spring 框架实现(AOP 切面)

// 1. 定义业务逻辑(纯净,无日志代码)
@Service
public class UserServiceImpl implements UserService {@Overridepublic void createUser(String username) {System.out.println("Creating user in database...");// 模拟数据库操作try {Thread.sleep(200);} catch (InterruptedException e) {e.printStackTrace();}}
}// 2. 定义切面(集中处理日志)
@Aspect
@Component
public class LoggingAspect {// 定义切点:拦截UserService接口的所有方法@Pointcut("execution(* com.example.service.UserService.*(..))")public void serviceMethods() {}// 前置通知@Before("serviceMethods()")public void beforeMethod(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();System.out.println("[INFO] Start method: " + methodName + ", args: " + Arrays.toString(args));}// 后置通知@AfterReturning("serviceMethods()")public void afterMethod(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();System.out.println("[INFO] Method completed: " + methodName);}// 环绕通知(计算方法执行时间)@Around("serviceMethods()")public Object aroundMethod(ProceedingJoinPoint pjp) throws Throwable {long startTime = System.currentTimeMillis();Object result = pjp.proceed();  // 执行目标方法long endTime = System.currentTimeMillis();System.out.println("[INFO] Time elapsed: " + (endTime - startTime) + "ms");return result;}
}// 3. 启用AOP(通过@EnableAspectJAutoProxy)
@Configuration
@ComponentScan(basePackages = "com.example")
@EnableAspectJAutoProxy
public class AppConfig {// 配置略
}

优势

  • 业务代码与日志逻辑完全分离,UserServiceImpl仅关注核心功能。
  • 日志逻辑集中在切面类,修改日志格式只需调整一处。
  • 可动态控制是否启用切面(如生产环境开启,测试环境关闭)。

1.2.3 事务管理:提供声明式事务管理,简化数据库事务处理。

维度Spring 框架下无框架下
实现方式提供声明式事务,通过@Transactional注解或 XML 配置即可控制事务(自动处理begincommit,异常时rollback),无需手动编写事务控制代码。需通过 JDBC 手动管理事务,
代码冗余且易出错(如忘记回滚、异常处理不完整)。
一致性保障事务传播行为(如REQUIREDREQUIRES_NEW)可通过配置控制,确保复杂业务(多方法调用)的事务一致性。复杂业务的事务一致性需手动协调(如多个方法共享一个连接),逻辑复杂且易出错。

 无框架实现(JDBC 手动管理事务)

public class UserServiceImpl implements UserService {private DataSource dataSource;  // 数据库连接池public UserServiceImpl(DataSource dataSource) {this.dataSource = dataSource;}@Overridepublic void transferMoney(String fromUser, String toUser, double amount) {Connection conn = null;try {// 1. 获取连接并开启事务conn = dataSource.getConnection();conn.setAutoCommit(false);  // 开启事务// 2. 业务操作1:扣款updateBalance(conn, fromUser, -amount);// 3. 模拟异常(测试回滚)if (amount > 1000) {throw new RuntimeException("金额超过限制");}// 4. 业务操作2:收款updateBalance(conn, toUser, amount);// 5. 提交事务conn.commit();} catch (Exception e) {// 6. 异常时回滚if (conn != null) {try {conn.rollback();} catch (SQLException ex) {ex.printStackTrace();}}throw new RuntimeException("转账失败", e);} finally {// 7. 关闭连接if (conn != null) {try {conn.setAutoCommit(true);  // 恢复默认提交模式conn.close();} catch (SQLException e) {e.printStackTrace();}}}}private void updateBalance(Connection conn, String username, double amount) throws SQLException {// JDBC操作略}
}

问题

  • 事务控制代码(获取连接、开启 / 提交 / 回滚事务)与业务逻辑混杂,代码冗长。
  • 异常处理复杂,易遗漏回滚操作导致数据不一致。
  • 若业务逻辑变更(如新增操作),需手动调整事务边界。

Spring 框架实现(声明式事务)

// 1. 配置数据源和事务管理器
@Configuration
@EnableTransactionManagement  // 启用事务管理
public class AppConfig {@Beanpublic DataSource dataSource() {// 配置数据源(如HikariCP)return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/test").username("root").password("password").build();}@Beanpublic PlatformTransactionManager transactionManager(DataSource dataSource) {return new DataSourceTransactionManager(dataSource);}
}// 2. 业务服务(使用@Transactional声明事务)
@Service
public class UserServiceImpl implements UserService {private JdbcTemplate jdbcTemplate;public UserServiceImpl(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}@Override@Transactional(rollbackFor = Exception.class)  // 声明式事务public void transferMoney(String fromUser, String toUser, double amount) {// 1. 扣款updateBalance(fromUser, -amount);// 2. 模拟异常if (amount > 1000) {throw new RuntimeException("金额超过限制");}// 3. 收款updateBalance(toUser, amount);}private void updateBalance(String username, double amount) {// 使用JdbcTemplate执行SQL(无需手动管理连接)jdbcTemplate.update("UPDATE users SET balance = balance + ? WHERE username = ?", amount, username);}
}

优势

  • 事务控制通过@Transactional注解声明,业务代码中无需手动处理连接、提交 / 回滚事务。
  • 异常时自动回滚(默认回滚RuntimeException及其子类),可通过rollbackFor自定义回滚条件。
  • 支持事务传播行为(如REQUIREDREQUIRES_NEW),适用于复杂业务场景。

1.2.4 MVC 架构:Spring MVC 框架支持构建灵活的 Web 应用,处理请求映射、视图解析等。

维度Spring 框架下(Spring MVC)无框架下
请求处理DispatcherServlet统一接收请求,通过@RequestMapping映射到具体控制器(Controller),职责清晰(前端控制器模式)。需手动编写多个 Servlet 处理不同请求,路由规则(如 URL 对应哪个处理类)分散在代码中,缺乏统一管理,新增请求时需手动注册 Servlet,扩展性差。
职责分离严格遵循 MVC:Model(业务数据)、View(页面展示)、Controller(请求处理)分离,通过视图解析器(ViewResolver)统一管理视图路径。视图逻辑(如 JSP 渲染)与业务逻辑(如数据库操作)常混杂在 Servlet 中,代码混乱,难以维护。
功能支持内置参数绑定(如表单数据自动映射到实体类)、数据校验(@Valid)、异常统一处理(@ExceptionHandler)等,减少重复代码。需手动解析请求参数(如request.getParameter())、手动校验数据、手动处理异常,代码冗余且易出错。

无框架实现:

// 1. 手动编写Servlet处理用户注册请求
@WebServlet("/register")
public class UserRegisterServlet extends HttpServlet {@Overrideprotected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {// 1. 获取请求参数(手动解析)String username = req.getParameter("username");String password = req.getParameter("password");// 2. 数据校验(手动实现)if (username == null || username.isEmpty()) {resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);resp.getWriter().write("Username is required");return;}// 3. 调用业务逻辑UserService userService = new UserServiceImpl();  // 手动创建Servicetry {userService.registerUser(username, password);resp.setStatus(HttpServletResponse.SC_OK);resp.getWriter().write("Registration successful");} catch (Exception e) {resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);resp.getWriter().write("Error: " + e.getMessage());}}
}// 2. 部署Servlet(需在web.xml中配置或使用@WebServlet注解)

问题: 

  • Servlet 职责混乱(同时处理参数解析、校验、业务逻辑、异常处理、视图渲染)。
  • 参数解析和校验逻辑重复(每个 Servlet 都需编写类似代码)。
  • 异常处理分散,难以统一管理。
  • 视图渲染与业务逻辑耦合(如直接在 Servlet 中输出 HTML)。

Spring 框架实现(Spring MVC)

// 1. 定义Controller处理请求
@RestController
@RequestMapping("/api/users")
public class UserController {private final UserService userService;public UserController(UserService userService) {this.userService = userService;}// 处理注册请求@PostMapping("/register")public ResponseEntity<?> registerUser(@RequestBody @Valid UserRegistrationRequest request) {// 1. 参数自动绑定到UserRegistrationRequest对象// 3. 调用业务逻辑userService.registerUser(request.getUsername(), request.getPassword());// 4. 返回响应(自动序列化为JSON)return ResponseEntity.ok("Registration successful");}// 5. 统一异常处理@ExceptionHandler(UserAlreadyExistsException.class)public ResponseEntity<?> handleUserAlreadyExists(UserAlreadyExistsException ex) {return ResponseEntity.status(HttpStatus.CONFLICT).body(ex.getMessage());}
}// 2. 数据模型(含校验注解)
@Data  // Lombok注解
public class UserRegistrationRequest {@NotBlank(message = "Username is required")private String username;@NotBlank(message = "Password is required")@Size(min = 6, message = "Password must be at least 6 characters")private String password;
}// 3. 启用Spring MVC(通过@SpringBootApplication)
@SpringBootApplication
public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

优势

  • 职责分离:Controller 仅负责请求路由和参数校验,业务逻辑由 Service 处理,视图渲染由视图解析器处理。
  • 参数自动绑定:通过@RequestBody@RequestParam自动将 HTTP 请求数据映射到 Java 对象。
  • 数据校验:通过 JSR-303 注解(如@NotBlank@Size)实现声明式校验,无需手动编写校验逻辑。
  • 统一异常处理:通过@ExceptionHandler集中处理特定异常,返回标准化错误响应。

1.2.5 集成支持:无缝集成各种技术(如 JDBC、ORM 框架、缓存、安全等)。

维度Spring 框架下无框架下
集成范围无缝集成主流技术:
通过 starter(如spring-boot-starter-data-redis)简化配置,无需手动处理技术细节。
集成技术需手动编写适配代码,
需解决技术间的兼容性(如版本冲突),开发效率低。
配置管理提供统一配置模型(如application.properties@Configuration),集中管理各技术的配置(如数据库连接、缓存过期时间)。配置分散在各技术的专属文件(如 JDBC 的db.properties、Redis 的redis.conf)中,需手动加载和维护,易出现配置不一致。

总结

通过上述示例可见:

  • Spring 框架通过注解(如@Autowired@Transactional)和容器(如ApplicationContext)简化对象管理和依赖注入,用 AOP 分离横切逻辑,用声明式事务管理数据库操作,用 MVC 架构统一处理 Web 请求,大幅减少重复代码,提升开发效率。
  • 无框架开发需手动处理对象创建、依赖关系、事务边界、Web 请求解析等底层细节,导致代码耦合度高、可维护性差。

选择 Spring 框架的核心价值在于 “聚焦业务,而非基础设施”,让开发者将更多精力投入到业务逻辑实现中。

http://www.lryc.cn/news/597300.html

相关文章:

  • 大模型开发
  • 【Ansible】Ansible 管理 Elasticsearch 集群启停
  • NAPI node-addon-api 编译报错 error C1083: “napi.h”: No such file or directory
  • 【esp32s3】GPIO 寄存器 开发解析
  • MACOS安装配置Gradle
  • 垃圾回收介绍
  • static 关键字的 特殊性
  • 双流join 、 Paimon Partial Update 和 动态schema
  • 【硬件-笔试面试题】硬件/电子工程师,笔试面试题-2,(电路分析/MOS管)
  • OpenLayers 快速入门(四)View 对象
  • PyTorch中nn.Module详解和综合代码示例
  • 大模型提示词漏洞攻防实战:从注入攻击到智能免疫系统的进化之路
  • mac电脑搭载c、c++环境(基于vs code)
  • 在mac 上zsh 如何安装最新的 go 工具
  • GRE实验
  • 微软Fabric重塑数据管理:Forrester报告揭示高ROI
  • 「iOS」——KVC
  • linxu CentOS 配置nginx
  • 【音视频学习】四、深入解析视频技术中的YUV数据存储方式:从原理到实践
  • 开源UI生态掘金:从Ant Design二次开发到行业专属组件的技术变现
  • 7月23日华为机考真题第二题-200分
  • 7月23日华为机考真题第一题100分
  • 关于原车一键启动升级手机控车的核心信息及注意事项
  • 将AI协作编程从“碰运气”的提示工程(Prompt Engineering)提升到“可预期”的上下文工程(Context Engineering)
  • 驯服AI的“魔法咒语”:Prompt提示词工程使用教程
  • [特殊字符] 从数据库无法访问到成功修复崩溃表:一次 MySQL 故障排查实录
  • 显微科研中的关键选择:不同显微镜相机技术特性与应用适配性全面解析
  • SpringBoot Stream实战指南
  • Django学习之旅--第13课:Django模型关系进阶与查询优化实战
  • 电科金仓推出AI融合数据库,开启国产数据库新时代