AOP
面向对象的特点继承、多态、封装。而封装就是要求功能分散到不同的对象中。也就是所让不同的类有不同的设计方法,这样代码就分散到一个个的类中去了,这样做的好处是降低了代码的复杂程度,使得可重用。
但是在分散代码的同时也增加了代码的重复性。比如说,在我们的两个类中,可能都需要在每个方法中做日志,也许日志的内容是完全相同的,但就是因为面向对象的设计让类之间无法联系,而不能将这些重复的代码统一起来。
一种办法:将这段代码写在一个独立的类中独立的方法里,然后再在这两个列中调用,但是这样这两个类就和这个独立的类耦合了,它的改变就会影响到这两个类。所以此方法不通。
另外一种办法:面向切面编程,它能够在需要的时候随意地加入代码,在运行时动态地将代码切入到类中的指定方法、指定位置上的编程思想就是面向切面编程。
这种切入到指定类指定方法的代码片段称为切面,而切入到哪些类、哪些方法则叫切入点。有了AOP,我们就可以把几个类共有的代码抽取到一个切片中,等到需要时在切入对象中去,从而改变其原有的行为。
AOP的概念:
1、通知(advice)
通知指的就是指拦截到连接点之后要执行的代码,通知分为前置、后置、异常、返回、环绕通知五类
2、连接点(joinpoint)
程序能够应用通知的一个“时机”,这些“时机”就是连接点,例如方法调用时、异常抛出时、方法返回后等等。
(被拦截到的点,因为Spring只支持方法类型的连接点,所以在Spring中连接点指的就是被拦截到的方法,实际上连接点还可以是字段或者构造器)
3、切入点(Pointcut)
(对连接点进行拦截的定义)
通知定义了切面要发生的“故事”,连接点定义了“故事”发生的时机,那么切入点就定义了“故事”发生的地点,例如某个类或方法的名称,Spring中允许我们方便的用正则表达式来指定。
4、切面(aspect)
通知、连接点、切入点组成了切面:时间、地点、要发生的故事
(类是对物体特征的抽象,切面就是对横切关注点的抽象)
5、引入(introduction)
引入允许向现有的类添加新的方法和属性
(在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段)
6.目标(Target)
即被通知的对象,如果没有AOP,那么通知的逻辑就要写在目标对象中,有了AOP之后它可以只关注自己要做的事,解耦合(代理的目标对象)
7.代理(proxy)
应用通知的对象,详细内容参见设计模式里面的动态代理模式。
8.织入(Weaving)
把切面应用到目标对象来创建新的代理对象的过程,织入一般发生在如下几个时机:
(1)编译时:当一个类文件被编译时进行织入,这需要特殊的编译器才可以做的到,例如AspectJ的织入编译器;
(2)类加载时:使用特殊的ClassLoader在目标类被加载到程序之前增强类的字节代码;
(3)运行时:切面在运行的某个时刻被织入,SpringAOP就是以这种方式织入切面的,原理应该是使用了JDK的动态代理技术。
使用AOP的几种方式
1.经典的基于代理的AOP
2.@AspectJ注解驱动的切面
3.纯POJO切面
4.注入式AspectJ切面