Spring Aop切面异常日志记录,本教程使用spring aop来记录service层所报出的异常记录,这样就可以很容易的知道我们项目的异常出现在哪个service方法中了,下面是spring aop异常切面的使用方法。
第一步:在我们的spring-context.xml中配置Aspectj自动代理,用于扫描我们自定义的异常处理切面类,代码如下。
<!-- 启用Aspectj自动代理 --> <aop:aspectj-autoproxy />
第二步:自定义我们spring aop异常处理的切面类,由于上面的aop配置,系统会自动扫描我们@Aspect注解中所定义的方法。
/** * 切面类 * @author Anson */ @Component @Aspect public class AopThrowsAdvice { private Logger logger = LoggerFactory.getLogger(getClass()); @Autowired private AopServiceComm aopServiceComm; //自定义service层 @Autowired private SqlSessionFactory sqlSessionFactory; /** *切面通知-执行前通知执行到了哪个方法 */ @Before("execution(* com.casking.cdds.modules.task.service.*.*(..))") public void beforeMethod(JoinPoint joinPoint) { Object object = joinPoint.getSignature(); String methodName = joinPoint.getSignature().getName(); List<Object> list = Arrays.asList(joinPoint.getArgs()); if (logger.isDebugEnabled()) { logger.debug("======================方法开始======================"); logger.debug(DateUtils.formatDateTime(new Date()) + "执行了【" + object + "方法开始执行......】"); } //自定义的方法保存日志信息,别在意 this.aopServiceComm.saveLogInfo(null,methodName,CommonVariate.TASK_SAVE_STARTONE); } /** *切面通知-异常通知 */ @AfterThrowing(value = "execution(* com.casking.cdds.modules.task.service.*.*(..))", throwing = "e") @Transactional(propagation=Propagation.NOT_SUPPORTED) public void afterThrowing(JoinPoint joinPoint, Exception e) { String methodName = joinPoint.getSignature().getName(); if (logger.isDebugEnabled()) { logger.info(methodName, e.toString() + "<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<,"); } //自定义的service层,保存异常信息,别在意 this.aopServiceComm.saveLogInfo(e,methodName,CommonVariate.TASK_SAVE_STARTTWO); } }
上述事务切面表达式说明:
- execution()是最常用的切点函数,
- 整个表达式可以分为五个部分: 1、execution(): 表达式主体。 - 2、第一个*号:表示返回类型,*号表示所有的类型。 - 3、包名:表示需要拦截的包名,后面的两个句点表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。 - 4、第二个*号:表示类名,*号表示所有的类。 - 5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数。
第三步:在spring-context.xml中配置事务驱动,这个每个ssm或ssh项目都是差不多的,如果有请别重复配置了,稍微改下就可以了。
<!-- 配置Annotation驱动,扫描有@Transactional注解的类方法,并执行事务 --> <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" order="5"/> <!-- 定义事务 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dynamicDataSource" /> </bean>
注意:异常事务是不能够被spring事务管理的,这里我写我踩过的坑,调低spring aop的执行顺序,order数字越小越靠前,可以在事务前执行异常记录sql。当事务管理数据源时会出现日志打印执行sql,如果不需要该方法执行事务,则可以手动去除事务,添加如下注解即可。
@Transactional(propagation=Propagation.NOT_SUPPORTED)