写在前面
数据结构的掌握程度决定你的coding之路能走多稳。
可能大家看到这个标题会很有疑问,怎么讲着讲着AOP开始讲起来排序了?
先说一下大家都比较熟悉的东西。回忆一下,我们如果想向容器中加入自定义的切面该怎么做?两种方法:
- 我们自定义Advisor注入到容器中。
- 利用@Aspect标示一个类为切面配置类,并利用@Around, @Before, @After, @AfterReturning, @AfterThrowing定义一些切面的实现,最后将切面配置类注入到容器中。
第一种方法我们后续会进行详细剖析。第二方法我想应该是大家比较常用的方式。而这又跟偏序排序有什么关系呢?
回想下第一篇搞懂AOP之一,拦截器链中我们说到拦截器链是List结构,而List结构注定有序。我们所使用的@Around, @Before, @After, @AfterReturning, @AfterThrowing最终也会被转换成MethodInterceptor加入到拦截器链中。那么问题来了,生成的拦截器链中的@Around, @Before, @After, @AfterReturning, @AfterThrowing顺序是如何的?谁在前,谁在后?(这里的顺序有两层含义,一是同一个切面配置类中的@Around, @Before, @After, @AfterReturning, @AfterThrowing顺序,二是多个切面配置类彼此的@Around, @Before, @After, @AfterReturning, @AfterThrowing顺序)
具体的顺序是什么我想大家在学习spring的时候都有了解过,但是这个顺序具体是如何实现的,就是我们要分析的内容,知其然也要知其所以然嘛。本文先讲一下偏序排序,在了解偏序排序的基础上,下一篇我们再深入偏序排序在AOP中的应用。
偏序关系
偏序关系是什么?我们可以从两个角度去解析。什么是“关系”?什么是“偏序”?
先来恶补一些离散数学的知识。
关系
“关系”是数字中的一个很基本的概念,站在集合的角度来看关系是怎么样的呢?
假设集合A={a,b,c,d,e,f},集合A中的元素表示6个人。其中a是b和c的爸爸,b是d的爸爸,c是e和f的爸爸。
那么集合A中的元素中符合父子关系的两个人可以用有序偶(a,b)、(a,c)、(b,d)、(c,e)、(c,f)表示。那么集合R={(a,b)、(a,c)、(b,d)、(c,e)、(c,f)}可以完整地描述出集合A中元素的父子管子,我们称R为集合A上的一个关系。
再举个栗子,集合A={1,2,3}上的小于关系可以表示为R={(1,2)、(1,3)、(2,3)}
现在我们把集合的个数扩充到两个
有两个集合A={a,b,c,d},B={x,y,z}。其中A表示a,b,c,d四位教师,x,y,z表示语文、数学和英语三门课程。a和b是语文老师、c是数学老师、d是英语老师。那么集合R={(a,x),(b,x),(c,y),(d,z)}表示教师和其所授课程之间的关系。
关系的表示
我们怎么表示关系呢?
1.关系矩阵
给定两个集合A={a1,a2…an}和B={b1,b1…bm},R是A到B的关系,则称
M R = [ c 11 c 12 ⋯ c 1 m c 21 c 23 ⋯ c 2 m ⋮ ⋮ ⋱ ⋮ c n 1 c n 2 ⋯ c n m ] M_R=\left[ \begin{matrix} c_{11} & c_{12} & \cdots & c_{1m} \\ c_{21} & c_{23} & \cdots & c_{2m} \\ \vdots & \vdots & \ddots & \vdots \\ c_{n1} & c_{n2} & \cdots & c_{nm} \\ \end{matrix} \right] MR=⎣⎢⎢⎢⎡c11c21⋮cn1c12c23⋮cn2⋯⋯⋱⋯c1mc2m⋮cnm⎦⎥⎥⎥