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,除非有必须释放的资源,但仍然需注意将e抛出给spring,并且finally不能由任何返回,否则spring同样认为没有异常发生
processTx中,
result=pjp.proceed(args);
前后,Spring捕捉到异常,会进行一系列处理,回滚等等,原则上也不进行try catch,
但此处考虑到异常的返回值,此处显式回滚,并定义异常返回值,在集中处理器中自行处理异常