AOP术语:spring
一、通知(Adivce)this
通知定义了切面是什么以及什么时候使用。除了描述切面要完成的工做,通知还解决了什么时候执行这个工做的问题。它应该应用于某个方法spa
个方法被调用以前?以后?以前和以后?仍是只在方法抛出异常时?代理
String 切面能够应用5种类型的通知orm
a、Before -- 在方法被调用以前调用通知对象
b、After -- 在方法被调用以后调用通知接口
c、After-returning -- 在方法成功执行以后调用通知生命周期
d、After-throwing -- 在方法抛出异常后调用通知ci
e、Around -- 通知包裹了被通知的方法,在被通知的方法调用以前和调用以后执行自定的行为get
二、链接点(Joinpoint)
链接点是在应用执行过程当中可以插入切面的一个点。
三、切点(Poincut)
四、切面(Aspect)
五、引入(Introduction)
引入容许咱们向现有的类添加新方法或属性。例如,咱们能够建立以个Auditable通知类,该类记录了对象最后一次修改时的
状态。这很简单,只需一种方法,setLastModified(Date),和一个实例变量来保存这个状态。而后,这个新方法和实例变量就
能够被引入到现有的类中。从而能够在无需修改这类现有的类的状况下,让他们具备新的行为和状态。
六、织入(Weaving)
织入是将切面应用到目标对象来建立新的代理对象的过程。切面在指定的链接点被织入到目标对象中。在目标对象的生命周期里
有多个点能够进行织入。
a、编译期 -- 切面在目标类编译时被织入。这种方式须要特殊的编译器。AspectJ的织入编译器就是以这种方式织入切面的。
b、类加载器 -- 切面在目标类加载到JVM时被织入。这种方式须要特殊的类加载器(ClassLoader),他能够在目标类被引入
应用以前加强该目标类的字节码。AspectJ5的LTW(loading-time weaving)就支持以这种方式织入切面
c、运行期 -- 切面在应用运行的某个时刻被织入。通常状况下,在织入切面时,AOP容器会为目标对象动态的建立一个代理对象。
Spring AOP 就是以这种方式织入切面的。
Spring 只支持方法链接点。 AspectJ和Jboss,除了方法切点,他们还提供了字段和构造器接入点 。Spring缺乏对字段链接点的支持,
没法让咱们建立细粒度的通知,例如拦截对象字段的修改。并且Spring也不支持构造器链接点,咱们也没法在Bean建立时应用通知。
Spring 的 AOP 配置元素简化了基于pojo切面的声明
AOP配置元素 描述
<aop:advisor> 定义aop通知器
<aop:after> 定义aop后置通知(无论被通知的方法是否执行成功)
<aop:after-returning> 定义AOP after-returning通知
<aop:after-throwing> 定义after-throwing通知
<aop:around> 定义AOP环绕通知
<aop:aspect> 定义切面
<aop:aspectj-autoproxy> 启用@Aspecctj注解驱动的去切面
<aop:before> 定义AOP前置通知
<aop:config> 顶层的aop配置,大多数的<aop:*>元素必须包含在<aop:config>元素内
<aop:declare-parents> 为被通知的对象引入额外的接口,并透明的实现
<aop:pointcut> 定义切点
经过切面引入新功能:
使用Spring AOP,咱们能够为Bean引入新的方法。代理拦截调用并委托给实现该方法的其余对象。咱们须要注意的是,当引入接口的
方法被调用时,代理将此调用委托给实现了新接口的某个其余独享。实际上,Bean的实现被拆分到了多个类。
新功能:
package com.springinaction.springidol
public interface Contestant{
void receiveAward();
}
<aop:aspect>
<aop:declare-parents
type-matching = "com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
default-impl="com.springinaction.springidol.GraciousContestant"
/>
</aop-aspect>
顾名思义,<aop:declare-parents>声明了此切面所通知的Bean在对他的对象层次结构中拥有新的父类型。
具体到本示例中,类型匹配Perpormer接口(由types-match属性指定)的那些Bean会实现Contestant接口(
由implements-interface属性指定)。最后要解决的问题是Constestant接口中的方法实现来自于何处
这里有两种方式标识所引入接口的实现。在本示例中,咱们使用default-impl属性经过他的全限定类名来显示
指定Contestant的实现。或者,咱们还可使用delegate-ref属性来标识.
<aop:aspect>
<aop:declare-parents
type-matching = "com.springinaction.springidol.Performer+"
implement-interface="com.springinaction.springidol.Contestant"
delegate-ref="contestaantDelegate"
/>
</aop-aspect>
delegate-ref 属性引用了一个Spring Bean做为引入的 委托。这须要在Spring上下文中存在一个ID为contestantDelefate
的Bean。
<bean id="contestaantDelegate" class="com.springinaction.springidol.GraciousContestant"/>
使用def-impl来直接标识委托和间接使用delegate-ref的区别在于后者是Spring Bean,他自己能够被注入,被通知,或者使用其余Spring配置
spring借助ApectJ的切点表达式语言来定义Spring切面
AspectJ指示器 描述
arg() 限制链接点匹配参数未指定类型的执行方法
@arg() 限制链接点匹配参数由指定注解标注的执行方法
execution() 用于匹配是链接点的执行方法
this() 显示链接点匹配AOP代理的Bean应用为指定类型的类
target() 限制链接点匹配目标对位为指定类型的类
@target() 限制链接点匹配特定的执行对象,这些对象对应的类要具有指定类型的注解
within() 限制链接点匹配指定的类型
@with() 限制链接点匹配指定注解所标注的类型(当使用AOP时,方法定义在由指定的注解所标注的类里)
@annotation 限制匹配带有指定注解链接点