IOC和AOP不是Spring提出的,在spring之前就已经存在,只不过更偏向于理论化,Spring在技术层次把这两个思想做了⾮常好的实现(Java)。
Spring核心思想
- IOC(Inversion of Control)
- 什么是IoC?
- IoC解决了什么问题
- IoC和DI的区别
- AOP(Aspect oriented Programming)
- 什么是AOP
- AOP在解决什么问题
- 为什么叫做⾯向切⾯编程
- AOP 的底层实现
- AOP 的动态代理技术
- JDK 的动态代理
- cglib 的动态代理
- AOP 相关概念
- 常见应用场景
IOC(Inversion of Control)
什么是IoC?
IoC Inversion of Control (控制反转/反转控制),注意它是⼀个技术思想,不是⼀个技术实现。
描述的事情:Java开发领域对象的创建,管理的问题
传统开发⽅式:⽐如类A依赖于类B,往往会在类A中new⼀个B的对象
IoC思想下开发⽅式:我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可。
我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列事情)
为什么叫做控制反转?
控制
:指的是对象创建(实例化、管理)的权利
反转
:控制权交给外部环境了(spring框架、IoC容器)
IoC解决了什么问题
IoC解决对象之间的耦合
问题
IoC和DI的区别
DI:Dependancy Injection(依赖注⼊)
怎么理解:
IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样罢了。
AOP(Aspect oriented Programming)
什么是AOP
AOP: AOP
为 Aspect Oriented Programming
的缩写,意思为面向切面编程,是通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP
是 OOP
的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
既然AOP是OOP的延续,我们从OOP说起,OOP
全称Object-Oriented Programming
(面向对象编程)。OOP是一种常用的编程范式,它以对象为核心,通过封装
、继承
和多态
等概念来组织和管理代码。面向对象编程提供了一种结构化和模块化的方法,使得我们能够更好地组织和复用代码。
OOP是⼀种垂直继承体系。
OOP编程思想可以解决⼤多数的代码重复问题,但是有⼀些情况是处理不了的,⽐如在顶级⽗类Animal中的多个⽅法中相同位置出现了重复代码,OOP就解决不了。
横切逻辑代码:
横切逻辑代码存在什么问题:
- 横切代码重复问题
- 横切逻辑代码和业务代码混杂在⼀起,代码臃肿,维护不⽅便
AOP
出场,AOP独辟蹊径提出横向抽取机制,将横切逻辑代码和业务逻辑代码分离。
代码拆分容易,那么如何在不改变原有业务逻辑的情况下,悄⽆声息的把横切逻辑代码应⽤到原有的业务逻辑中,达到和原来⼀样的效果,这个是⽐较难的。
AOP在解决什么问题
在不改变原有业务逻辑情况下,增强横切逻辑代码,根本上解耦合,避免横切逻辑代码重复。
为什么叫做⾯向切⾯编程
「切」:指的是横切逻辑,原有业务逻辑代码我们不能动,只能操作横切逻辑代码,所以⾯向横切逻辑
「⾯」:横切逻辑代码往往要影响的是很多个⽅法,每⼀个⽅法都如同⼀个点,多个点构成⾯,有⼀个⾯的概念在⾥⾯。
AOP 的底层实现
实际上,AOP 的底层是通过 Spring 提供的的动态代理技术实现的。在运行期间,Spring通过动态代理技术动态的生成代理对象,代理对象方法执行时进行增强功能的介入,在去调用目标对象的方法,从而完成功能的增强。
AOP 的动态代理技术
常用的动态代理技术
JDK
代理 : 基于接口
的动态代理技术cglib
代理:基于父类
的动态代理技术
JDK 的动态代理
JDK的动态代理实现如下:
- 创建目标类接口:
public interface TargetInterface {
public void method();
}
- 目标类
public class Target implements TargetInterface {
@Override
public void method() {
System.out.println("Target running....");
}
}
- 动态代理代码
Target target = new Target(); //创建目标对象
//创建代理对象
TargetInterface proxy = (TargetInterface) Proxy.newProxyInstance(target.getClass()
.getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("前置增强代码...");
Object invoke = method.invoke(target, args);
System.out.println("后置增强代码...");
return invoke;
}
}
);
- 调用代理对象的方法测试验证:
// 测试,当调用接口的任何方法时,代理对象的代码都无序修改
proxy.method();
输出如下:
cglib 的动态代理
cglib 的动态代理实现如下:
- 创建目标类:
public class Target {
public void method() {
System.out.println("Target running....");
}
}
- 动态代理代码
Target target = new Target(); //创建目标对象
Enhancer enhancer = new Enhancer(); //创建增强器
enhancer.setSuperclass(Target.class); //设置父类
enhancer.setCallback(new MethodInterceptor() { //设置回调
@Override
public Object intercept(Object o, Method method, Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("前置代码增强....");
Object invoke = method.invoke(target, objects);
System.out.println("后置代码增强....");
return invoke;
}
});
Target proxy = (Target) enhancer.create(); //创建代理对象
- 调用代理对象的方法测试
//测试,当调用接口的任何方法时,代理对象的代码都无序修改
proxy.method();
默认情况下,Spring会根据被代理对象是否实现接⼝
来选择使⽤JDK还是CGLIB。当被代理对象没有实现任何接⼝时,Spring会选择CGLIB。当被代理对象实现了接⼝,Spring会选择JDK官⽅的代理技术,不过我们可以通过配置的⽅式,让Spring强制使⽤CGLIB。
AOP 相关概念
Spring 的 AOP 实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。
后续我会讲解AOP的操作,在此之前我们必须理解 AOP 的相关术语,常用的术语如下:
Target(目标对象)
:代理的目标对象Proxy (代理)
:一个类被 AOP 织入增强后,就产生一个结果代理类Joinpoint(连接点)
:所谓连接点是指那些被拦截到的点。在spring中,这些点指的是方法,因为spring只支持方法类型的连接点Pointcut(切入点)
:所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义Advice(通知/ 增强)
:所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知Aspect(切面)
:是切入点和通知(引介)的结合Weaving(织入)
:是指把增强应用到目标对象来创建新的代理对象的过程。spring采用动态代理织入,而AspectJ采用编译期织入和类装载期织入
常见应用场景
日志记录
:AOP可用于在方法调用前后记录日志。这对于系统的调试、错误排查以及性能分析都非常有用。通过在切面中编写日志记录逻辑,可以捕获方法的参数、返回值和执行时间等信息,并将其记录到日志文件或其他目标中。安全性控制
:AOP可用于实现安全性控制,如身份验证、权限验证和访问控制等。通过在切面中编写安全性逻辑,可以在方法调用前检查用户的身份和权限,从而确保只有合法用户才能执行敏感操作。事务管理
:AOP广泛应用于事务管理,确保数据库操作的一致性和完整性。通过在切面中应用事务逻辑,可以在方法调用前后自动开启、提交或回滚事务。这样,开发者无需手动编写事务管理代码,而是将关注点集中在业务逻辑上。缓存管理
:AOP可用于实现缓存管理,提高系统的性能和响应速度。通过在切面中添加缓存逻辑,可以在方法执行前检查缓存是否包含所需数据,避免执行相同的方法调用。如果缓存中存在数据,则直接返回缓存数据,减少对底层存储系统的访问。异常处理
:AOP可用于捕获和处理方法调用过程中的异常情况。通过在切面中编写异常处理逻辑,可以记录异常信息、发送通知或执行特定的异常处理策略。这有助于更好地理解和响应系统中发生的异常情况。性能监控
:AOP可用于监控方法的性能指标,以便进行性能分析和优化。通过在切面中添加性能监控逻辑,可以记录方法的执行时间、调用次数和资源消耗等指标。这样可以识别系统中的性能瓶颈,并采取相应的优化措施。
总之,Spring AOP提供了一种模块化的方式来处理横切关注点,使开发者能够更好地关注核心业务逻辑。通过在切面中编写特定的逻辑,可以在方法调用的不同阶段插入通用的横切行为,提高代码的可维护性和重用性。
本文内容到此结束了,
如有收获欢迎点赞👍收藏💖关注✔️,您的鼓励是我最大的动力。
如有错误❌疑问💬欢迎各位指出。
主页:共饮一杯无的博客汇总👨💻保持热爱,奔赴下一场山海。🏃🏃🏃