深入解析 Spring IOC AOP:原理、源码与实战
深入解析 Spring IOC & AOP:原理、源码与实战
Spring 框架的核心在于 IOC(控制反转) 和 AOP(面向切面编程)。今天,我们将深入剖析它们的原理,结合源码解析,并通过 Java 代码实战来掌握这两个核心概念。
📌 1. 什么是 IOC(控制反转)?
IOC(Inversion of Control)是 Spring 的核心思想,它将对象的创建和依赖关系的管理交给 Spring 容器,避免了传统的 new
关键字实例化方式。
🔥 1.1 IOC 机制
Spring 使用 BeanFactory
和 ApplicationContext
管理 Bean 的生命周期,主要流程如下:
- 读取配置(XML 或注解)
- 实例化 Bean(通过
BeanFactory
) - 依赖注入(通过
@Autowired
) - Bean 生命周期管理
📌 2. 手写简易 IOC 容器
我们用 Java 代码手写一个简化版的 IOC 容器,模拟 Spring 依赖注入的实现。
📝 代码示例:
import java.util.HashMap;
import java.util.Map;
// 模拟 Spring 容器
class SimpleIOC {
private Map<String, Object> beanContainer = new HashMap<>();
// 注册 Bean
public void registerBean(String name, Object obj) {
beanContainer.put(name, obj);
}
// 获取 Bean
public Object getBean(String name) {
return beanContainer.get(name);
}
}
// 测试 IOC 容器
class UserService {
public void sayHello() {
System.out.println("Hello, Spring IOC!");
}
}
public class TestIOC {
public static void main(String[] args) {
SimpleIOC ioc = new SimpleIOC();
ioc.registerBean("userService", new UserService());
UserService userService = (UserService) ioc.getBean("userService");
userService.sayHello();
}
}
🔍 运行结果
Hello, Spring IOC!
✅ 分析:
SimpleIOC
充当 Spring 容器,存储和管理 Bean 实例。registerBean()
方法模拟ApplicationContext
注册 Bean 的功能。getBean()
方法模拟getBean(Class<T> clazz)
获取对象。
📌 3. 什么是 AOP(面向切面编程)?
AOP(Aspect-Oriented Programming)通过 动态代理 在方法执行前后加入额外逻辑,常用于 日志、事务、权限控制 等场景。
🔥 3.1 AOP 机制
Spring AOP 主要通过 JDK 动态代理(基于接口)和 CGLIB(基于子类)实现。
📖 3.2 Spring AOP 代理模式
Spring AOP 主要使用 代理模式,在目标方法执行前后执行增强逻辑,如:
@Before
(前置通知)@AfterReturning
(后置通知)@Around
(环绕通知)
📌 4. 手写 AOP 代理(JDK 动态代理)
我们使用 JDK 动态代理 实现 AOP,模拟 Spring @Transactional
事务管理。
📝 代码示例:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
// 业务接口
interface UserService {
void createUser();
}
// 业务实现类
class UserServiceImpl implements UserService {
public void createUser() {
System.out.println("创建用户...");
}
}
// AOP 代理类
class AOPProxy implements InvocationHandler {
private Object target;
public AOPProxy(Object target) {
this.target = target;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开启事务...");
Object result = method.invoke(target, args);
System.out.println("提交事务...");
return result;
}
// 生成代理对象
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new AOPProxy(target));
}
}
// 测试 AOP 代理
public class TestAOP {
public static void main(String[] args) {
UserService userService = new UserServiceImpl();
UserService proxyService = (UserService) AOPProxy.getProxy(userService);
proxyService.createUser();
}
}
🔍 运行结果
开启事务...
创建用户...
提交事务...
✅ 分析:
AOPProxy
通过 JDK 动态代理 在方法调用前后加入事务逻辑。getProxy()
生成代理对象,并拦截UserService
的方法调用。- 运行后,
createUser()
方法被代理增强,实现 AOP 事务管理功能。
📌 5. Spring AOP 实战(@Aspect)
在 Spring 中,我们可以使用 @Aspect
和 @Around
注解实现 AOP 事务管理。
📝 代码示例:
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TransactionAspect {
@Before("execution(* com.service.*.*(..))")
public void beginTransaction() {
System.out.println("开启事务...");
}
@After("execution(* com.service.*.*(..))")
public void commitTransaction() {
System.out.println("提交事务...");
}
}
🌟 关键点
@Aspect
:声明 AOP 切面类@Before
/@After
:在方法执行前/后执行事务逻辑execution(* com.service.*.*(..))
:匹配com.service
包下的所有方法
📌 6. 总结
功能 | Spring 机制 | 手写代码 |
---|---|---|
IOC | 依赖注入(DI) | 手写 BeanFactory |
AOP | 事务管理、日志 | JDK 动态代理 |
Spring AOP | @Aspect 切面 | @Before 、@After |
✅ 今日收获:
- 理解了 IOC 机制,并手写 IOC 容器
- 掌握了 AOP 代理机制,并手写 JDK 动态代理
- 结合 Spring @Aspect 注解,掌握 AOP 事务管理
🚀 明日预告:Spring MVC 深度解析(DispatcherServlet、HandlerMapping、拦截器)
🔗 学习资料:
📖 Spring 官方文档
💬 你对 Spring IOC & AOP 有什么疑问?欢迎留言交流! 🚀