![]() |
![]() |
AOP就是通过代理(Proxy)的方式来实现的。 |
使得真实角色处理的业务更加纯粹,不再去关注一些公共的事情。
公共的业务由代理来完成 --- 实现了业务的分工。
公共业务发生扩展时变得更加集中和方便。
|
- 切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于@Aspect注解的方式来实现。
- 连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。
- 通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。
- 切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。
- 引入(Introduction):用来给一个类型声明额外的方法或属性(也被称为连接类型声明(inter-type declaration))。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入来使一个bean实现IsModified接口,以便简化缓存机制。
- 目标对象(Target Object): 被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
- AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
- 织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
通知类型:
- 前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
- 后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
- 异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
- 最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
- 环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
|
AOP的重要性:很重要。
Spring AOP就是将公共的业务(如:日志、安全等)和领域业务结合。当执行领域业务时,将会把公共业务加进来。实现公共业务的重复
利用。领域业务更纯粹。程序员专注于领域业务。
其本质还是动态代理。
|
Spring提供类型检查的异常通知(typed throws advice),这意味着org.springframework.aop.
ThrowsAdvice接口不包含任何方法:它只是一个标记接口用来标识所给对象实现了一个或者多个针对特定类型的异常通知方法。这些方法应当满足下面的格式:
afterThrowing([Method, args, target],subclassOfThrowable)
只有最后一个参数是必须的。根据异常通知方法对方法及参数的需求,方法的签名可以有一个或者四个参数。
public
class
ExceptionLog
implements
ThrowsAdvice {
public
void
afterThrowing(Exception
ex
)
throws
Throwable {
}
}
|
下面是一些异常通知的例子。
当一个RemoteException(包括它的子类)被抛出时,下面的通知会被调用:
public
class
RemoteThrowsAdvice
implements
ThrowsAdvice {
public
void
afterThrowing(RemoteException
ex
)
throws
Throwable {
// Do something with remote exception
}
}
当一个ServletException被抛出,下面的通知将被调用。 和上面的通知不同,它声明了4个参数,因此它可以访问被调用的方法,方法的参数以及目标对象:
public
class
ServletThrowsAdviceWithArguments
implements
ThrowsAdvice {
public
void
afterThrowing(Method
m
, Object[]
args
, Object
target
, ServletException
ex
) {
// Do something with all arguments
}
}
最后一个例子说明怎样在同一个类里使用两个方法来处理 RemoteException和ServletException。可以在一个类里组合任意数量的异常通知方法。
public
static
class
CombinedThrowsAdvice
implements
ThrowsAdvice {
public
void
afterThrowing(RemoteException
ex
)
throws
Throwable {
// Do something with remote exception
}
public
void
afterThrowing(Method
m
, Object[]
args
, Object
target
, ServletException
ex
) {
// Do something with all arguments
}
}
|