关于Spring的那点事(1)
“什么是Spring?什么是Spring boot?什么是Spring Cloud?”
这是本次要探讨的话题,认识Java很久了,用Spring做日常开发也十好几年了,但究竟这几个东东是什么?怎么产生的?解决了什么问题?有哪些利弊?有没有其他可替代的方案?……今天,我需要好好思考一下这些问题。
简单来说:
- Spring:Java 企业级开发的基础框架
- Spring Boot:快速构建 Spring 应用的脚手架
- Spring Cloud:微服务架构的一站式解决方案
关于Spring
Spring框架的核心思想可以概括为IoC(控制反转)和AOP(面向切面编程),这两大特性构成了Spring的技术基石,贯穿了从底层设计到上层应用的各个层面。以下是具体解析:
一、IoC(Inversion of Control)控制反转
1. 核心概念
- 传统开发痛点:对象依赖关系由代码硬编码控制(如
UserService userService = new UserServiceImpl()
),导致组件间强耦合,难以测试和扩展。 - IoC解决方案:将对象的创建和依赖关系管理交给Spring容器,通过配置(XML/注解)描述组件间关系,实现“控制权反转”。
// 传统方式:主动创建依赖 public class OrderService {private UserService userService = new UserServiceImpl(); // 硬编码依赖 }// IoC方式:通过容器注入依赖 public class OrderService {@Autowired // 由Spring容器自动注入private UserService userService; }
2. IoC的实现方式
- 依赖注入(DI):最常见的实现方式,通过构造器、Setter方法或字段注入依赖。
- 依赖查找(DL):通过名称从容器中查找对象(如
applicationContext.getBean("userService")
),但不如DI灵活。
3. 带来的优势
- 解耦组件:代码仅关注业务逻辑,无需关心依赖对象的创建过程。
- 可测试性:可通过Mock对象轻松进行单元测试。
- 灵活性:修改依赖关系只需调整配置,无需修改代码。
二、AOP(Aspect-Oriented Programming)面向切面编程
1. 核心概念
- 横切关注点:日志、事务、权限校验等功能在多个模块中重复出现,传统OOP难以复用。
- AOP解决方案:将这些通用功能抽象为切面(Aspect),在运行时动态织入到目标方法中。
// 示例:用AOP记录方法执行时间 @Aspect public class PerformanceAspect {@Around("execution(* com.example.service.*.*(..))")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long start = System.currentTimeMillis();Object result = joinPoint.proceed(); // 执行目标方法System.out.println(joinPoint.getSignature() + " executed in " + (System.currentTimeMillis() - start) + "ms");return result;} }
2. AOP的实现机制
- 动态代理(默认方式):基于接口的JDK动态代理,或基于子类的CGLIB代理。
- 编译时织入:通过AspectJ等工具在编译阶段修改字节码。
3. 带来的优势
- 代码复用:避免在多个模块中重复编写日志、事务等代码。
- 可维护性:通用逻辑集中管理,修改时只需调整切面。
- 低侵入性:无需修改原有业务代码,通过注解或配置即可实现功能增强。
三、IoC与AOP的协同价值
- IoC为AOP提供基础:Spring容器管理的Bean才能被AOP动态代理。
- AOP增强IoC组件:通过切面为IoC管理的Bean添加额外功能(如事务、缓存)。
- 典型应用场景:
- 声明式事务管理(
@Transactional
)ÿ
- 声明式事务管理(