spring aop 切面测试

spring 配置 aop

    <aop:config>
        <aop:aspect id="asp1" ref="monitorApi">
            <!-- 配置一个切入点,相当于@Pointcut -->
            <aop:pointcut expression="execution(* com.xxx.xxx.impl.service.*.*(..))" id="simplePointcut"/>
            <aop:before method="serviceBefore" pointcut-ref="simplePointcut" />
            <aop:after method="release" pointcut-ref="simplePointcut" />
            <aop:after-returning method="serviceAfter"  pointcut-ref="simplePointcut" returning="rvt" />
            <aop:around method="processTx" pointcut-ref="simplePointcut" />
            <aop:after-throwing pointcut-ref="simplePointcut" method="afterThrow" throwing="ex"/>
        </aop:aspect>
    </aop:config>

切面类:

package com.changhang.urgoo.impl.utils;

import com.changhang.urgoo.impl.entity.result.MesResult;
import com.changhang.urgoo.impl.entity.result.SpResult;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

public class MonitorApi{
  /**
   * 通知前
   * @date 2016年9月27日 上午9:18:10
   * @Title before
   * @Description 
   * @param jp void 
   * @throws
   */
  public void serviceBefore(JoinPoint jp) {

//    System.out.println("被代理方法名字:"+jp.getSignature().getName());
//    System.out.println("被代理方法参数:"+jp.getArgs().toString());
//    System.out.println("被代理对象:"+jp.getTarget());
//    System.out.println("模拟权限验证");
 
  
          
  }

  /**
   * 
   * @date 2016年9月27日 上午9:18:29
   * @Title log
   * @Description 
   * @param jp
   * @param rvt void 
   * @throws
   */
  public  void serviceAfter(JoinPoint jp, Object rvt){
	  long start= System.currentTimeMillis();
    System.out.println("被代理方法名字:"+jp.getSignature().getName());
    System.out.println("被代理方法参数:"+jp.getArgs());
    System.out.println("被代理对象:"+jp.getTarget());
    System.out.println("被代理对象的返回值"+rvt);
    System.out.println("现在调用的是日志管理");
    long end= System.currentTimeMillis();
    System.err.println(">>>>>>>>>>>日志处理时间共:"+(end-start)+" 毫秒");
  }
  
/**
 * 
 * @date 2016年9月27日 上午9:18:53
 * @Title processTx
 * @Description 
 * @param pjp
 * @return
 * @throws Throwable Object
 * @throws
 */
public Object processTx(ProceedingJoinPoint pjp) throws Throwable
{
    long start= System.currentTimeMillis();
    System.out.println("现在调用的是事务开启");
    //得到业务方法的参数
    Object[] args=pjp.getArgs();
    System.out.println("业务方法的参数:"+args.toString());

//     Object result = pjp.proceed(args);
    //被代理对象的业务方法
    Object result = null;
    try{
        result=pjp.proceed(args);
        System.out.println("现在调用的是事务提交或回滚");
        long end= System.currentTimeMillis();
        System.err.println(">>>>>>>>>>>事物处理时间共:"+(end-start)+" 毫秒");
        return result;

    } catch (Exception e) {
     //   e.printStackTrace();     // 此处不进行打印,交由spring委托afterThrow进行打印
        TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
        SpResult sr = new SpResult();
        sr.setHeaderCode("400");
        sr.setHeaderMessage(MesResult.messageInfo(MesResult.SERVER_BUSY, null));
        sr.setBody(null);
        return sr;
        //throw e;

    } finally {

        ;

    }

}

    /**
   *  
   * @date 2016年9月27日 上午9:19:43
   * @Title release
   * @Description  void 
   * @throws
   */
  public void release(){
    System.out.println("资源已经被释放!");
  }

//配置抛出异常后通知,使用在方法aspect()上注册的切入点

	public void afterThrow(JoinPoint jp, Exception ex){
		  long start= System.currentTimeMillis();
		    System.out.println("被代理方法名字:"+jp.getSignature().getName());
		    System.out.println("被代理方法参数:"+jp.getArgs());
		    System.out.println("被代理对象:"+jp.getTarget());
		    System.out.println("被代理对象的返回值"+ex);
        ex.printStackTrace();
		    System.out.println("现在调用的是异常管理");
		    long end= System.currentTimeMillis();
		    System.err.println(">>>>>>>>>>>异常处理时间共:"+(end-start)+" 毫秒");
		System.err.println("------------afterThrow---------------");
	}
}

service:

@Service
@Transactional
public class TestService extends BaseService{

	@Autowired
	private TestAccessor testAccessor;

	public SpResult aop(Map<String,String> map) {
		SpResult sp = new SpResult();
		testAccessor.insertTest(map);
		testAccessor.selectTest();

		return sp;
	}

	public SpResult withoutaop(Map<String,String> map) {
		SpResult sp = new SpResult();
		try{
			testAccessor.insertTest(map);
			testAccessor.selectTest();
		} catch (Exception e) {
		//	e.printStackTrace();
			//TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			throw new RuntimeException(e);
		} finally {
			;
		}

		return sp;
	}
}


其中 insertTest正常,selectTest异常

函数aop完全不考虑异常,由Spring来全程捕捉处理,到了processTx中,集中处理

函数withoutaop则有try catch代码,扔出throw new RuntimeException(e);,效果等同于aop,如果此处没有扔出,则切面代理会走around -------- after-returning,因为spring不认为由异常发生,

扔出后,走around ------- after-throwing

注意,在catch中一般需要throw出异常,否则自行处理则spring认为没有异常在service发生,将不会回滚,当然也可以在catch中显式回滚:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

但是这样所有函数代码变得冗长不好维护,不如不进行try catch操作,原则上service层不进行try catch,有必须释放的资源则finally throw return ,但仍然需注意将e抛出给spring,并且finally不能由任何返回,否则spring同样认为没有异常发生(finally throw return )

processTx中,

result=pjp.proceed(args);

前后,Spring捕捉到异常,会进行一系列处理,回滚等等,原则上也不进行try catch,

但此处考虑到异常的返回值,此处显式回滚,并定义异常返回值,在集中处理器中自行处理异常

原文地址:https://www.cnblogs.com/silyvin/p/9106828.html