起源:blog.csdn.net/duxd185120/article/details/109210224
学习一个模块的设计次要是看接口设计,通过接口设计咱们就可能从整体晓得模块怎么实现的,具体实现就是组装这些接口来进行实现的,晓得了模块接口设计,实现也就变得很简略了。
本文次要从 aop 背景出发点,来本人去想须要哪些接口,就可能形容一个模块的功能设计规定。
AOP 产生背景
应用面向对象编程(OOP)有一些弊病,当须要为多个不具备继承关系的对象引人同一个公共行为时,例如日志、平安检测等,咱们只有在每个对象里援用公共行为,这样程序中就产生了大量的反复代码,程序就不便于保护了,所以就有了一个对面向对象编程的补充,即面向方面编程(AOP ), AOP 所关注的方向是横向的,区别于 OOP 的纵向。
什么是 AOP
什么是面向方面编程,3 个过程:
- 找到横切点:首要指标确定在程序的哪个地位进行横切逻辑
- 横切逻辑(业务代码):横切逻辑代码,这个就是横切业务代码,与 aop 无关
- 织入:将横切逻辑织入到横切点
开发者次要关怀的是横切逻辑的编写,只须要很少的代码编写确定横切点有哪些,而不须要去为每个横切点增加横切逻辑,不然就是面向对象编程了。
既然是横向的编程,那么在咱们的程序中,哪些能够作为横线切入点呢?
看下示例代码:
public class Test {public static void main(String[] args) {
//@1
B b = new B();
//@2
b.method();
//@3
B.say();}
static class B {
// 字段
//@4
private String name;
// 构造方法
public B() {//@1.1}
// 对象办法
public void method(){//@2.2}
// 静态方法
static void say(){//@3.3}
}
}
所以咱们能够将横切点次要分为两大类:字段、办法。办法又分为很多种,
横切点有很多中央,从代码上看得见的,有如下几个中央:
- 应用构造函数创建对象
-
- 构造函数执行
- 对象办法调用
-
- 对象办法执行
- 静态方法调用
-
- 静态方法执行
- 反射读写对象字段
指标 1:找到横切点
那么怎么去定义一个横切点呢?怎么用一个接口来形容一个横切点呢?
在 Java 中,所有皆对象,在 Java 中一个类有 2 方面内容:字段、办法(构造函数、对象办法、静态方法),java 中应用 AccessibleObject 来形象公共行为。办法:就是一段能够执行的程序,一段代码。
所以在横切点接口中,首先一个性能就是返回给用户以后横切点,有两种状况:
- 如果横切点作用于对象(对象字段、对象办法、构造函数),则不仅须要返回 AccessibleObject,还须要返回以后对象,因为调用通过反射调用对象办法须要传入以后对象。
- 如果横切点作用于类,则仅返回 AccessibleObject 即可。
另一个接口性能就是要不要思考在横切点来管制多个横切逻辑的调用。这个能够有框架反对,也能够由横切点管制。这对应的就是责任链模式的 API 设计。比方 tomcat 中的 Filter 链式调用就是以汇合模式调用;netty 中的 Handler 组织就是以链表模式。如果是以汇合模式调用,则在横切点接口须要定义一个办法来链式调用。(aop 联盟的 JoinPoint 采纳是汇合模式调用)
那么 AOP 联盟应用 JointPoint 接口来定义横切点。
public interface Joinpoint {Object proceed() throws Throwable;
Object getThis();
AccessibleObject getStaticPart();}
Object proceed() throws Throwable
: 链式调用横切点
Object getThis();
返回连接点以后对象。如果以后连接点是动态,比方静态方法,则该办法返回 null,因为反射不须要对象,而且静态方法是通过类调用的,压根就没有对象,所以返回 null。spring aop 不反对静态方法的拦挡,所以在 spring 中这里返回的就是指标对象(被代理对象)
AccessibleObject getStaticPart();
返回连接点动态局部,对于连接点是办法,返回的就是 Method 对象。
当初对连接点的设计比拟清晰了,而后就是对连接点的扩大了,比方可执行程序(构造方法、Method)的子接口,字段的子接口(aop 联盟没有定义,只有办法级别的)。
AOP 联盟对连接点接口的设计:
比方在 MethodInvocation,就是返回 Method。
指标 2:横切逻辑(加强)形象定义
加强的形象,其实就须要连接点信息,毕竟加强是要投入到一个中央的,所以须要连接点信息。
在 aop 联盟的接口定义:
Advice 作为一个 tag 标识,在 aop 联盟中应用拦截器来作为加强的命名,这里齐全能够去掉 Interceptor,而间接定义一个 MethodAdvice。之所以定义为 Interceptor,是因为拦截器命名更合乎编程命名标准,让人从命名就晓得接口性能。
在 MethodInterceptor,传入连接点信息(因为是办法拦挡,所以这里是办法级别的连接点接口定义)
Object invoke(MethodInvocation invocation) throws Throwable;
指标 3:织入
首先就是怎么织入。织入由两种计划。
- 动态织入:采纳自定义类加载器机制。自定义类加载器依据织入规定在加载 class 文件期间对 class 文件入手织入横切逻辑,而后将改变后的 class 文件交给 JVM 运行。
- 动静织入:由多种抉择,动静代理(JDK Proxy)、动静字节码生成技术(cglib)
spring 采纳动静织入。动静织入就是生成代理对象,代理对象中保护了以后连接点所有拦截器,而后调用指标办法时被代理类拦挡,在代理类中作 aop 性能。
来一个残缺的流程图:
Spring AOP 的实现基于 AOP 联盟接口标准设计实现的,全局看下 aopalliance 有哪些接口以及接口的 API 设计,咱们下面曾经剖析完了。
AOP 联盟的接口很少:
近期热文举荐:
1.1,000+ 道 Java 面试题及答案整顿 (2022 最新版)
2. 劲爆!Java 协程要来了。。。
3.Spring Boot 2.x 教程,太全了!
4. 别再写满屏的爆爆爆炸类了,试试装璜器模式,这才是优雅的形式!!
5.《Java 开发手册(嵩山版)》最新公布,速速下载!
感觉不错,别忘了顺手点赞 + 转发哦!