AOP是一向面向切面的技术,刚开始学习的时候很难理解思想,随着使用和学习的增多,对AOP也有了一定的认识,遂记录下来 方便日后查阅复习。
本文思路:
1.要学习AOP,先要知道这些东西
2.通过代理技术实现AOP
这里直接通过三个demo的形式说明问题
3.通过AOP的第三方框架 AspectJ 来认识AOP
这里介绍注解和xml的方式使用 AspectJ 来实现 AOP
带着问题来学习:AOP 只是一个工具,它能解决我的哪些问题?
一、要学习 AOP,先要知道这些东西
AOP是一种面向切面的编程思想,spring有自己的原理(动态代理)实现了AOP的功能要求,AspectJ作为独立的第三方框架,也运用其他技术实现了AOP的功能要求,Spring只是整合了AspectJ框架,并不是Spring就包含了AspectJ框架,两者都是框架,平级地位。
1.常见术语的理解
public class UserDao {
public void addUser(){
System.out.println("添加用户.....");
}
public void updateUser(){
System.out.println("更新用户....");
}
public void deleteUser(){
System.out.println("删除用户.....");
}
public void queryUser(){
System.out.println("查询用户....");
}
}
1)Joinpoint(连接点)
连接点是一种说法,可以进行增强的方法我就叫它连接点。比如上方的UserDao类中有四个方法,现在这四个方法都是 可以 被增强的,那么这四个方法都叫做 连接点。
什么叫增强,看下面。这里注意理解 可以 ,指具备这种能力。这种能力就是只要是方法就有可能被增强,至于最后到底要不要增强看业务的需求。
这个类中 有4个连接点。
2)Pointcut(切入点)
切入点是连接点的特殊情况,上面说到连接点是可能被增强的方法,切入点就是确定下来就是要增强的方法。如业务需求:我们需要对addUser()这个方法进行增强,那么就 可以称addUser()这个方法就是一个切入点。
切入点的个数不像上面连接点的个数当类生成就确定多少个,业务上需要增强几个方法,就有几个切入点。
3)Advice(通知/增强)
前面一直说增强增强,这里就说到了。增强简单的理解就是 我不动原代码(UserDao)里的方法,通过第三方对这个方法进行额外的处理。
比如:我需要拦截到addUser()的方法,在程序执行这个方法之前和之后各打印一句日志信息。这里打印的日志信息就是对addUser()方法的额外操作,被称为增强。
增强一般有五种形式,这个后面单独介绍。
增强针对方法级别的,拦截方法并进行额外的操作。
4)Introduction(引介)
增强的概念是拦截方法并进行额外的操作,引介可以理解为特殊的增强,但它拦截的不是方法,而是类。引介是类级别的操作。
比如:这里引介 UserDao 类,进行的操作主要有 :在程序运行期间动态的添加 属性 或者 方法。
5)Target(目标对象)
目标对象就是指被代理对象,增强的原理就是 创建一个代理对象,将增强的内容都放到代理对象里进行。
业务需求:为UserDao类的addUser()方法在执行前和执行后添加日志信息。在 3)Advice(通知/增强) 里只说到了要这么做,这里就说到了怎么做。具体过程是代理对象里处理的。代理对象可以简单的理解为一个类,不理解代理的可以看前几篇文章有介绍到 代理机制的学习。
这里的目标对象就是 UserDao 类。
6)Weaving(织入)
织入是一个过程。指将 增强 应用到 目标对象 来创建新的代理对象里这样一个过程。
7)Proxy(代理)
在 Target(目标对象) 里提到了 目标对象就是被代理对象,而Proxy 就是代理对象。可以理解代理是目标对象的经纪人,帮助处理一些目标对象不方便处理的事情。
代理对象 可以认为是一个类。
8)Aspect(切面)
切面 是切入点和通知的结合。
比如对于UserDao来说,现在业务需求我要对 addUser()方法进行增强,那么addUser()方法就是一个切入点;对这个切点进行哪种形式的增强呢,比如是前置增强(下面就说到5中增强方式),那么这里的 addUser()方法和前置增强在一起就称为一个切面。
从汉语的角度来说就是:对 某某某(哪些切入点) 进行 某某某的操作(哪种增强方式)这样一个完整过程。
啰嗦两句:spring 里的切面只有一个切入点和一个增强组成,而AspectJ里的切面可以由多个切点和多个增强组成。
通常 Spring的切面不叫Aspect,有另外一种称呼叫做:Advisor。
2.增强的5中方式:(通知和增强是一个概念,叫法不同而已)
1)前置通知
在原方法执行之前会执行的通知。
2)后置通知
在原方法执行之后才会执行的通知。
3)环绕通知
简单理解为: 前置通知 + 后置通知。
4)异常抛出通知
当程序出错了,需要抛出异常才会执行的通知。
5)最终通知
简单理解和异常里try..catch..finally里的finally比较相像,不管怎么样,都会执行的通知。
其中spring 实现的AOP只有前面四种通知,而AspectJ具备五种通知方式。