第一步,首先说问题,表明这个技术诞生的原因
§ OOP面向对象编程存在的问题
AOP指面向切面编程,可以看作OOP面向对象编程的一种补充完善。OOP引入了封装、继承、多态等概念建立具有层级关系的对象模型,适合定义纵向关系。但不适合定义横向关系,例如日志功能。日志功能往往散布于核心业务逻辑代码中的各个地方,导致大量代码重复,不利于各个模块的复用(这一点对于go项目里面体现的很明显,散布于各处的log代码,dao层里面有,service层里面有,controller层里面也有)。
§ AOP针对这个问题而出现
AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性
§ www.cnblogs.com/xrq730/p/49…
o 第二步,解释技术中的基本概念,以及简单使用方式
§ AOP中引入了一些相关概念
· Advice:增强,就是一段执行某个功能的代码
· 连结点:任何方法执行时的那一刻,都可以是连结点
· 切点:是一种描述信息,规定了哪些 join point 可以执行哪些 advice
· 目标对象:织入 advice 的目标对象. 目标对象也被称为 advised object.
· 代理对象:一个类被 AOP 织入 advice, 就会产生一个结果类, 它是融合了原类和增强逻辑的代理类
· 织入:将 aspect 和其他对象连接起来, 并创建 adviced object 的过程
o 动态代理织入, 在运行期为目标类添加增强(Advice)生成子类的方式??
o Spring 采用动态代理织入, 而AspectJ采用编译器织入和类装载期织入
· Advice类型:
o before advice, 在 join point 前被执行的 advice.
o after return advice, 在一个 join point 正常返回后执行的 advice
o after throwing advice, 当一个 join point 抛出异常后执行的 advice
o after(final) advice, 无论一个 join point 是正常退出还是发生了异常, 都会被执行的 advice
o around advice, 在 join point 前和 joint point 退出后都执行的 advice. 这个是最常用的 advice
§ AOP使用例子,在现在用SpringBoot框架的情况下,都是用注解
· @ Aspect, @ PointCut, @ Before, @ After, @ AfterReturning, @ AfterThrowing, @ Around
o 第三步,介绍技术的原理
§ AOP低层使用代理模式实现,代理模式以及Java中的代理模式
· 简单理解:就是在原始对象的基础上前后增加一些功能,形成一个增强版的代理类对象
· 在java中,根据代理创建的时间,可以分为静态代理和动态代理
o 静态代理:代理类已经写好了,在程序运行前代理类的 .class 文件就已经存在了
§ 静态代理的问题:一个代理只能服务于一个特定的业务实现类
o 动态代理(最重要的,AOP默认使用JDK动态代理):动态代理可以帮助我们仅仅在需要的时候再创建代理类,减少资源浪费,此外由于动态代理是一个模板的形式,也可以减少程序的代码量
§ java中实现动态代理的步骤、实现方式(这个地方不好粘代码,看idea里面的吧)
§ segmentfault.com/a/119000004…
o Cglib代理,它的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强。使用cglib实现动态代理,完全不受代理类必须实现接口的限制。
§ developer.huawei.com/consumer/cn…
基本概念
- Joinpoint
-
- Spring AOP只支持方法执行类型的JoinPoint
- Pointcut :
-
- AOP中的顶级接口之一(org.springframework.aop.Pointcut),用来匹配哪些Joinpoint可以织入
- 规定了两个方法
- ClassFilter getClassFilter():对JointPoint所处对象进行Class级别的类型匹配
- MethodMatcher getMethodMatcher():对JointPoint进行方法级别的匹配
- Advice :
-
- 代表织入JointPoint的横切逻辑,如果将Aspect比作Class,那么Advice即使Method
- 根据执行实际分为三种Advice:MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice,即Advice的三个子接口
- Interceptor
-
- AOP Alliance对Around Advice的叫法,拦截器中封装了Advice,与Advice对应,也有三种拦截器分别封装对应的Advice,即,MethodBeforeAdviceInterceptor,AfterReturningAdviceInterceptor,ThrowsAdviceInterceptor三个实现类
- 实现类中包含了Advice对象和invoke()方法,不同的Advice增强位置invoke略有区别
- MethodBeforeAdviceInterceptor源码和UML图:
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
/**
* Create a new MethodBeforeAdviceInterceptor for the given advice.
* @param advice the MethodBeforeAdvice to wrap
*/
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
- Introduction
-
- 一种特殊的Advice,和根据JointPoint执行时机不同而区别的Advice不同,而是根据可以完成的功能而区分
- Aspect
-
- PointCut和Advice的封装(即封装了哪些地方进行拦截,以及拦截后执行什么操作),在AOP Alliance中被称为Advisor
- 织入和织入器
-
- ProxyFactory
- Target
-
- 构造器输入一个Object,类中包含一个Object属性,即输入bean对其进行简单的封装,基本没有啥功能
- 和构造器模式中的Target不一样