`
zyongking
  • 浏览: 57346 次
  • 性别: Icon_minigender_1
  • 来自: 湖北
社区版块
存档分类
最新评论

Spring进行面向切面编程(AOP)

阅读更多

1AOP概念

首先让我们从定义一些重要的AOP概念开始。这些术语不是Spring特有的。 不幸的是,Spring术语并不是特别的直观;如果Spring使用自己的术语,将会变得更加令人困惑。 

· 切面(Aspect: 一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。 在Spring AOP中,切面可以使用通用类(基于模式的风格) 或者在普通类中以 @Aspect 注解(@AspectJ风格)来实现。
例:每个方法都要加日志,以及到处都要处理事务..这都构成了一个方面

· 通知(Advice: 在切面的某个特定的连接点(Joinpoint)上执行的动作。通知有各种类型,其中包括“around”“before”“after”等通知。 通知的类型将在后面部分进行讨论。许多AOP框架,包括Spring,都是以拦截器做通知模型, 并维护一个以连接点为中心的拦截器链。
例:要执行的动作,如日志代码 

· 目标对象(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)提供另外一种角度来思考程序结构,通过这种方式弥补了面向对象编程(OOP)的不足。

2、通知的类型:(详见附件3

前置通知(Before advice): 在某连接点(join point)之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。 

org.springframework.aop.MethodBeforeAdvice

后置通知(After (finally) advice): 当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。 

org.springframework.aop.AfterReturningAdvice

抛出异常后通知(After throwing advice): 在方法抛出异常退出时执行的通知。 
org.springframework.aop.ThrowsAdvice

环绕通知(Around Advice): 包围一个连接点(join point)的通知,如方法调用。这是最强大的一种通知类型。 环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它们自己的返回值或抛出异常来结束执行。

org.aopalliance.intercept.MethodInterceptor

通知(Advice)顺序

如果有多个通知想要在同一连接点运行会发生什么?Spring AOP 的执行通知的顺序跟AspectJ的一样。 在“进入”连接点的情况下,最高优先级的通知会先执行

3Spring 2.0 "@AspectJ"使用了Java 5 ( AspectJ 5的注解,可以将切面声明为普通的Java类。 使用了AspectJ 提供的一个库来做切点(pointcut)解析和匹配。 但是,AOP在运行时仍旧是纯的Spring AOP,并不依赖于AspectJ 的编译器或者织入器(weaver)。

spring 2.0引入了一个简单并且功能更加强大的方法来自定义aspect。自定义aspect时有两种风格:schema-based@aspectJ

1. @aspectJ风格指在一个正常的java类上添加java 5的注解来声明一个aspect,它是由AspectJ项目提出的,详细信息请查看http://www.eclipse.org/aspectj 。
见附件3

2. shcema-based风格是指在spring bean的配置文件中通过新的"aop"命名空间标记定义一个aspect。 
见附件3

@aspectJ风格

@Aspect

public class Example {

  @Before("execution(* com.xyz.myapp.dao.*.*(..))")

  public void doAccessCheck() {

// ...

  }


  @AfterReturning(

pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",

returning="retVal")

  public void doAccessCheck(Object retVal) {

// ...

  }


  @AfterThrowing(

pointcut="com.xyz.myapp.SystemArchitecture.dataAccessOperation()",

throwing="ex")

  public void doRecoveryActions(DataAccessException ex) {

// ...

  }


  @After("com.xyz.myapp.SystemArchitecture.dataAccessOperation()")

  public void doReleaseLock() {

// ...

  }


  @Around("com.xyz.myapp.SystemArchitecture.businessService()")

  public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {

// start stopwatch

Object retVal = pjp.proceed();

// stop stopwatch

return retVal;

  }


}

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics