AOP术语详解

==== 关注点 (Concern)==== java

关注点就是咱们要考察或解决的问题。如订单的处理,用户的验证、用户日志记录等都属于关注点。express

 

关注点中的核心关注点 (Core Concerns) ,是指系统中的核心功能,即真正的商业逻辑。如在一个电子商务系统中,订单处理、客户管理、库存及物流管理都是属于系统中的核心关注点。编程

 

还有一种关注点叫横切关注点 (Crosscutting Concerns) ,他们分散在每一个各个模块中解决同同样的问题,跨越多个模块。如用户验证、日志管理、事务处理、数据缓存都属于横切关注点。 缓存

 

 AOP 的编程方法中,主要在于对关注点的提起及抽象 。咱们能够把一个复杂的系统看做是由多个关注点来有机组合来实现,一个典型的系统可能会包括几个方面的关注点,如核心业务逻辑、性能、数据存储、日志、受权、安全、线程及错误检查等,另外还有开发过程当中的关注点,如易维护、易扩展等。 安全

 

 

==== 切面 (Aspect) ==== 框架

 

切面是一个关注点的模块化 ,这个关注点可能会横切多个对象和模块,事务管理是横切关注点的很好的例子。它是一个抽象的概念,从软件的角度来讲是指在应用程序不一样模块中的某一个领域或方面 。 模块化

在 Spring 2.0 AOP 中,切面可使用基于 XML Schema 的风格 或者以 @Aspect 注解 ( @AspectJ 风格)来实现 函数

 

下面的例子是基于 xml schema 风格来定义一个 Aspect( 红字部分 ) : 性能

<aop:aspect id="aspectDemo" ref="aspectBean"> spa

< aop:pointcut id = "myPointcut" expression = "execution(* package1.Foo.handle*(..)" /> 

< aop:before pointcut -ref = "myPointcut" method = "doLog" /> 

</aop:aspect > 

 

这个定义的意思是:每执行到 package1.Foo 类的以 handle 开头的方法前,就会先执行 aspectBean  doLog 方法 

 

 

==== 链接点 (Join point) ==== 

 

链接点就是在程序执行过程当中某个特定的点,好比某方法调用的时候或者处理异常的时候。这个点能够是一个方法、一个属性、构造函数、类静态初始化块,甚至一条语句。 而对于 SPRING 2.0 AOP 来讲,链接点只能是方法,这个必定要记住~!每个方法均可以当作为一个链接点,只有被归入某个 CutPoint  JointPoint 才有可能被 Advice  

 

经过声明一个org.aspectj.lang.JoinPoint 类型的参数可使通知(Advice)的主体部分得到链接点信息。

 

JoinPoint 与CutPoint 之间的关系见下面的CutPoint 的讲解

 

==== 切入点 (Pointcuts) ==== 

切入点指一个或多个链接点,能够理解成链接电点的集合 . Advice 是经过 Pointcut 来链接和介入进你的 JointPoint 的。 

 

好比在前面的例子中,定义了 

< aop:pointcut id = "myPointcut" 

expression = "execution(* package1.Foo.handle*(..)" /> 

那么这就是定义了一个PointCut ,该Pointcut 表示“在package1.Foo类全部以handle开头的方法”

假设package1.Foo类里相似于:

    Public class Foo { 

       public handleUpload(){..} 

       public handleReadFile(){..} 

       .....

    }

那么handleUpload 是一个JointPoint ,handleReadFile 也是一个Joint,那么上面定义的id=”myPointcut” 的PointCut 则是这两个JointPoint 的集合

 

==== 通知 (Advice) ==== 

Advice定义了切面中的实际逻辑(即实现 ) ,好比日志的写入的实际代码。换一种说法Advice 是指在定义好的切入点处,所要执行的程序代码  

 

通知有如下几种:

前置通知( Before advice  :在切入点匹配的方法执行以前运行使用@Before 注解来声明

 

返回后通知( After returning advice  :在切入点匹配的方法返回的时候执行。使用 @AfterReturning 注解来声明

 

抛出后通知( After throwing advice  : 在切入点匹配的方法执行时抛出异常的时候运行。使用 @AfterThrowing 注解来声明

 

后通知( After (finally) advice  :不论切入点匹配的方法是正常结束的,仍是抛出异常结束的,在它结束后(finally)后通知(After (finally) advice)都会运行。使用 @After 注解来声明。这个通知必须作好处理正常返回和异常返回两种状况。一般用来释放资源。

 

环绕通知( Around Advice  :环绕通知既在切入点匹配的方法执行以前又在执行以后运行。而且,它能够决定这个方法在何时执行,如何执行,甚至是否执行。在环绕通知中,除了能够自由添加须要的横切功能之外,还须要负责主动调用链接点 ( 经过 proceed) 来执行激活链接点的程序 。 请尽可能使用最简单的知足你需求的通知。(好比若是前置通知也能够适用的状况下,就不要使用环绕通知) 

 

环绕通知使用 @Around 注解来声明。并且该通知对应的方法的第一个参数必须是 ProceedingJoinPoint 类型 。在通知体内(即通知的具体方法内),调用 ProceedingJoinPoint 的 proceed() 方法来执行链接点方法 。 

 

 

==== 引入 (Introduction) ==== 

引入是指给一个现有类添加方法或字段属性,引入还能够在不改变现有类代码的状况下,让现有的 Java 类实现新的接口 (以及一个对应的实现 )。相对于 Advice 能够动态改变程序的功能或流程来讲,引介 (Introduction) 则用来改变一个类的静态结构 。好比你可使用一个引入来使bean实现 IsModified 接口,以便简化缓存机制

 

 

==== 目标对象( Target Object  ==== 

被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫作 被通知(advised) 对象。 既然Spring AOP是经过运行时代理实现的,这个对象永远是一个 被代理(proxied )对象。

 

 

==== AOP 代理( AOP Proxy  ==== 

AOP框架建立的对象,用来实现切面契约(aspect contract)(包括通知方法执行等功能)。 在Spring中,AOP代理能够是JDK动态代理或者CGLIB代理。注意:Spring 2.0 最新引入的基于模式( schema-based )风格和 @AspectJ 注解风格的切面声明,对于使用这些风格的用户来讲, AOP 代理的建立是透明  。

 

Spring 缺省使用 J2SE 动态代理( dynamic proxies  来做为 AOP 的代理。这样任何接口均可以被代理。 

Spring 也支持使用 CGLIB 代理 . 对于须要代理类而不是代理接口的时候 CGLIB 代理是颇有必要的 。 若是一个业务对象并无实现一个接口,默认就会使用 CGLIB 。 做为 面向接口编程 的最佳实践,业务对象一般都会实现一个或多个接口。 

==== 织入( Weaving  ==== 

把切面(aspect)链接到其它的应用程序类型或者对象上,并建立一个被通知(advised)的对象,这样一个行为就叫作Weaving。 这些能够在编译时(例如使用AspectJ 编译器),类加载时和运行时完成。 Spring 和其余纯 Java AOP 框架同样,在运行时完成织入 。

 

其实织入的方式有3种:

一、运行时织入-即在 java运行的过程当中,使用Java提供代理来实现织入。根据代理产生方式的不一样,运行时织入又能够进一步分为J2SE动态代理及动态字节码生成两种方式。因为J2SE动态代理只能代理接口,所以,须要借助于一些动态字节码生成器来实现对类的动态代理。大多数 AOP 实现都是采用这种运行时织入的方式,包括 Spring 。

 

二、类加载器织入-指经过自定义的类加载器,在虚拟机 JVM加载字节码的时候进行织入,好比AspectWerkz ( 已并入 AspecJ )  JBoss 就使用这种方式 。 

 

三、编译器织入-使用专门的编译器来编译包括切面模块在内的整个应用程序,在编译的过程当中实现织入,这种织入是功能最强大的。编译器织入的 AOP实现通常都是基于语言扩展的方式,即经过对标准java语言进行一些简单的扩展,加入一些专用于处理AOP模块的关键字,定义一套语言规范,经过这套语言规范来开发切面模块,使用本身的编译器来生成java字节码。AspectJ 主要就是是使用这种织入方式 。 

 

PS: 

链接点(join point): 它是指应用中执行的某个点,即程序执行流程中的某个点。如执行某个语句或者语句块、执行某个方法、装载某个类、抛出某个异常……,Spring目前只支持方法级别的。

切入点(pointcut): 切入点是链接点的集合,它一般和通知(Advice)联系在一块儿,是切面和程序流程的交叉点。好比说,定义了一个pointcut,它将抛出异常 ClassNotFoundException和某个通知联系起来,那么在程序执行过程当中,若是抛出了该异常,那么相应的通知就会被触发执行。 Spring中是实现了MethodInterceptor,通俗一点说,在链接点上,切入点决定在什么状况下调用哪一个Advice。

装备(advice): 指切面在程序运行到某个链接点所触发的动做。在这个动做种咱们能够定义本身的处理逻辑。通知须要利用切入点和链接点联系起来才会被触发。目前AOP定义了五种通知:前置通知(Before advice)、后置通知(After advice)、环绕通知(Around Advice)、异常通知(After throwing advice)、返回后通知(After returning advice)。