spring aop 环绕通知around和其他通知的区别

您所在的位置:网站首页 round跟around的区别 spring aop 环绕通知around和其他通知的区别

spring aop 环绕通知around和其他通知的区别

2023-11-12 15:11| 来源: 网络整理| 查看: 265

前言:

     spring 的环绕通知和前置通知,后置通知有着很大的区别,主要有两个重要的区别:

1) 目标方法的调用由环绕通知决定,即你可以决定是否调用目标方法,而前置和后置通知   是不能决定的,他们只是在方法的调用前后执行通知而已,即目标方法肯定是要执行的。

2)  环绕通知可以控制返回对象,即你可以返回一个与目标对象完全不同的返回值,虽然这很危险,但是你却可以办到。而后置方法是无法办到的,因为他是在目标方法返回值后调用

   这里是经过我自己测试的过的例子,使用面向切面来处理一些问公共的问题,比如,权限管理,事务的委托

下面的例子就是使用环绕通知,当程序发生异常时,重复提交请求,重复的次数是可以设定的

    当我们开发企业级应用时,通常会想要从几个切面来引用模块化的应用和特定操作的集合,下面是一个典型的通用切面,看起来可能像下面这样(这也是Spring文档里的)

 

package test.prefer.aspect;

import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;

@Aspectpublic class SystemArchitecture {

  /**   * A join point is in the web layer if the method is defined   * in a type in the com.xyz.someapp.web package or any sub-package   * under that.   */  @Pointcut("within(com.xyz.someapp.web..*)")  public void inWebLayer() {}

  /**   * A join point is in the service layer if the method is defined   * in a type in the com.xyz.someapp.service package or any sub-package   * under that.   */  @Pointcut("within(com.xyz.someapp.service..*)")  public void inServiceLayer(){}

  /**   * A join point is in the data access layer if the method is defined   * in a type in the com.xyz.someapp.dao package or any sub-package   * under that.   */  @Pointcut("within(com.xyz.someapp.dao..*)")  public void inDataAccessLayer(){}

  /**   * A business service is the execution of any method defined on a service   * interface. This definition assumes that interfaces are placed in the   * "service" package, and that implementation types are in sub-packages.   *    * If you group service interfaces by functional area (for example,    * in packages com.xyz.someapp.abc.service and com.xyz.def.service) then   * the pointcut expression "execution(* com.xyz.someapp..service.*.*(..))"   * could be used instead.   *   * Alternatively, you can write the expression using the 'bean'   * PCD, like so "bean(*Service)". (This assumes that you have   * named your Spring service beans in a consistent fashion.)   */  @Pointcut("execution(* test.prefer.aspect.*.*(..))")  public void businessService(){}    /**   * A data access operation is the execution of any method defined on a    * dao interface. This definition assumes that interfaces are placed in the   * "dao" package, and that implementation types are in sub-packages.   */  @Pointcut("execution(* com.xyz.someapp.dao.*.*(..))")  public void dataAccessOperation(){}

}

 

 一、定义自己的一个切面

/**文件名:ConcurrentOperationExecutor.Java*描述:*修改人:Administrator*/

package test.prefer.aspect;

import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.springframework.core.Ordered;

/** * @author  *@date 2010-6-1 */@Aspectpublic class ConcurrentOperationExecutor implements Ordered {      private static final int DEFAULT_MAX_RETRIES = 2;

   private int maxRetries = DEFAULT_MAX_RETRIES;   private int order = 1;

   public void setMaxRetries(int maxRetries) {      this.maxRetries = maxRetries;   }      public int getOrder(){      return this.order;   }   public void setOrder(int order){      this.order = order;   }      @Around("test.prefer.aspect.SystemArchitecture.businessService()")   public Object doConcurrentOperation(ProceedingJoinPoint pjp) throws Throwable {     //环绕通知处理方法      int numAttempts = 0;      Exception lockFailureException;      do {         numAttempts++;         try {           System.out.println("环绕通知方法[ doConcurrentOperation(ProceedingJoinPoint pjp) ].............");            return pjp.proceed();         }         catch(Exception ex) {            lockFailureException = ex;         }      }      while(numAttempts



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3