java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring IoC和AOP核心原理

Spring IoC和AOP的核心原理是什么详解

作者:用户85116027612

Spring框架是Java企业级应用开发中的核心框架之一,其核心思想可以概括为IOC和AOP,这篇文章主要介绍了Spring IoC和AOP的核心原理是什么的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下

前言

Spring 最核心的两个能力就是 IoCAOP

IoC 解决的是“对象由谁创建、谁维护”的问题,AOP 解决的是“如何在不修改业务代码的前提下,给方法统一增强功能”的问题。

一、Spring IoC 的核心原理

1. 什么是 IoC

IoC 全称是 Inversion of Control,控制反转

在传统开发中,一个对象如果依赖另一个对象,通常会在类内部自己去创建:

class UserService {
    private UserDao userDao = new UserDao();
}

这样做的问题是,业务类自己掌握了依赖对象的创建权,类与类之间耦合很高。

而在 Spring 中,对象不再自己创建依赖,而是交给 Spring 容器统一管理:

@Service
class UserService {
    @Autowired
    private UserDao userDao;
}

这就是控制反转:
原本由程序自己控制对象的创建和依赖关系,现在反过来交给 Spring 容器控制。

2. IoC 的本质

IoC 的本质就是三件事:

所以,Spring IoC 容器本质上可以理解成一个“高级对象工厂”。

3. IoC 的底层实现原理

Spring IoC 能实现,核心依赖以下几个东西:

(1)配置元数据

Spring 需要知道哪些类要交给容器管理、对象之间如何依赖,这些信息来自配置元数据,例如:

这些元数据最终都会被 Spring 解析成统一的内部结构:BeanDefinition

BeanDefinition 可以理解为 Bean 的定义信息,里面记录了:

(2)反射机制

Spring 创建对象和注入依赖时,不可能把所有类写死,因此底层需要依赖 Java 的 反射机制 来动态完成:

例如:Spring 通过反射创建 Bean 实例,再通过反射给属性赋值,完成依赖注入。

(3)容器机制

Spring 提供了 IoC 容器来统一管理 Bean,核心接口有:

容器负责保存 BeanDefinition、创建 Bean、注入依赖、执行生命周期回调、维护单例池等。

4. IoC 的工作流程

Spring IoC 的大体流程如下:

第一步:读取配置

Spring 启动后,会读取 XML、注解、配置类等元数据。

第二步:解析成 BeanDefinition

Spring 将这些元数据统一解析成 BeanDefinition,并注册到 BeanDefinitionRegistry 中。

第三步:实例化 Bean

Spring 根据 BeanDefinition,通过反射创建对象实例。

第四步:依赖注入

Spring 将当前 Bean 所依赖的其他 Bean 注入进来。
注入方式常见有:

这里常说的 DI(Dependency Injection,依赖注入) ,其实就是 IoC 的具体实现方式。
也就是说:

第五步:初始化

Bean 完成依赖注入之后,会执行一系列初始化逻辑,例如:

第六步:放入容器缓存

如果是单例 Bean,会放到单例池中,后续直接复用。

第七步:销毁

容器关闭时,会调用销毁方法,例如:

二、Spring AOP 的核心原理

1. 什么是 AOP

AOP 全称是 Aspect Oriented Programming,面向切面编程

它的目标是:
把日志、事务、权限、监控、异常处理等横切逻辑从业务代码中抽离出来,统一处理。

比如很多业务方法都要做日志打印、事务控制,如果每个方法里都手写,会造成大量重复代码。AOP 就是为了解决这种问题。

2. AOP 的本质

AOP 的本质就是:

在目标方法执行前、执行后或异常时,动态插入增强逻辑。

Spring AOP 的底层核心实现,就是 动态代理

3. AOP 的核心概念

理解 Spring AOP,通常要掌握以下几个概念:

(1)切面 Aspect

封装横切逻辑的类,例如日志切面、事务切面。

(2)连接点 JoinPoint

程序执行过程中可以被拦截的位置。
在 Spring AOP 中,主要指 方法执行

(3)切点 Pointcut

定义“哪些方法需要被增强”。
比如:

execution(* com.demo.service.*.*(..))

表示拦截某个包下所有类的所有方法。

(4)通知 Advice

在连接点执行的增强逻辑。常见通知有:

(5)目标对象 Target

原始业务对象。

(6)代理对象 Proxy

Spring 为目标对象生成的代理对象,调用方拿到的通常是它,而不是原始对象。

4. Spring AOP 的底层实现:动态代理

Spring AOP 不是直接修改原始类,而是为原始对象创建一个代理对象。
外部调用方法时,实际上调用的是代理对象的方法,代理对象会在调用前后织入增强逻辑。

例如:

proxy.save() {
    before();
    target.save();
    after();
}

5. Spring AOP 的两种代理方式

(1)JDK 动态代理

如果目标类实现了接口,Spring 默认优先使用 JDK 动态代理。

特点:

(2)CGLIB 动态代理

如果目标类没有实现接口,Spring 会使用 CGLIB 动态代理。

特点:

因此它有一些限制:

6. AOP 的执行流程

Spring AOP 的典型执行流程是:

第一步,Spring 先通过 IoC 创建原始 Bean。

第二步,在 Bean 初始化过程中,Spring 会判断该 Bean 是否匹配切面规则。

第三步,如果匹配,就为它创建代理对象。

第四步,容器最终保存的往往不是原始对象,而是代理对象。

第五步,业务代码调用方法时,先进入代理对象。

第六步,代理对象按照责任链顺序执行各种通知。

第七步,最后才真正调用目标方法。

比如事务场景下:

这也是为什么 @Transactional 能生效,本质就是 AOP 代理在起作用。

三、IoC 与 AOP 的关系

IoC 和 AOP 的关系可以概括为一句话:

AOP 不是独立存在的,它是建立在 IoC 之上的。

Spring 先通过 IoC 把 Bean 创建出来,再在初始化阶段判断是否需要 AOP,如果需要,就返回代理对象。

因此可以说:

AOP 是 IoC 容器在 Bean 生命周期中的一个扩展能力。

四、总结

Spring IoC 的核心原理是控制反转和依赖注入。Spring 会读取 XML、注解或配置类中的元数据,将其解析成 BeanDefinition,再通过反射实例化对象并完成依赖注入、初始化和生命周期管理,从而把对象的创建和维护交给容器统一控制。

Spring AOP 的核心原理是动态代理。Spring 在 Bean 创建完成后,会判断该 Bean 是否匹配切面规则,如果匹配,就为它创建代理对象。外部调用方法时,实际调用的是代理对象,代理对象会在目标方法前后织入增强逻辑。若目标类实现了接口,通常使用 JDK 动态代理;否则使用 CGLIB 动态代理。AOP 常用于事务、日志、权限控制等横切逻辑。

到此这篇关于Spring IoC和AOP的核心原理是什么的文章就介绍到这了,更多相关Spring IoC和AOP核心原理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文