AOP实战

AOP实战

一、定义AOP切面

package com.aop.service;
​
import com.alibaba.fastjson.JSONObject;
import com.tf56.core.BizReturn;
import com.tf56.core.exception.BizError;
import com.tf56.hermesContract.exception.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
​
import java.lang.reflect.Method;
​
@Component
@Aspect
@Slf4j
public class AopAspectService {
​
    @Pointcut("execution(* com.aop.service.impl.*.*(..))")
    private void pointcut() {
        log.info("pointcut");
    }
​
    /**
     * 调用服务前对入参进行入参记录
     * @param joinPoint
     */
    @Before(value = "pointcut()")
    public void before(JoinPoint joinPoint) {
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = joinPoint.getSignature().getName();
        StringBuilder str = new StringBuilder();
        str.append("before: ")
                .append(className)
                .append("@")
                .append(methodName)
                .append(" , params: ");
        Object[] args = joinPoint.getArgs();
        for (Object arg : args) {
            str.append(JSONObject.toJSONString(arg) + ", ");
        }
        log.info(str.toString());
    }
​
    @AfterReturning(value = "pointcut()", returning = "returnObj")
    public void afterReturn(Object returnObj) {
        String res = JSONObject.toJSONString(returnObj);
        log.info("afterReturning: " + (res.length() > 2000 ? res.substring(0, 2000) + "......" : res));
    }
​
    @AfterThrowing(value = "pointcut()", throwing = "e")
    public void afterThrowing(Throwable e) {
        log.error("afterThrowing: " + e.getMessage(), e);
    }
​
    @Around(value = "pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        Long begin = System.currentTimeMillis();
        StringBuilder str = new StringBuilder("around: ");
        Object result = null;
        try {
            result = proceedingJoinPoint.proceed();
        } catch (BusinessException bse) {
            log.error(str + bse.getMessage(), bse);
            if (checkTransactional(proceedingJoinPoint)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            return BizReturn.createError(new BizError(bse.getErrorCode(), bse.getMessage(), null));
        } catch (RuntimeException e) {
            log.error(str + e.getMessage(), e);
            if (checkTransactional(proceedingJoinPoint)) {
                TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            }
            return BizReturn.createError(e.getMessage());
        }
        Long end = System.currentTimeMillis();
        str.append(" 执行时间: ").append(end - begin).append("ms");
        log.info(str.toString()); // 记录接口执行时间
        return result;
    }
​
    /**
     * 判断是否有事务注解
     * @param proceedingJoinPoint
     * @return
     */
    private boolean checkTransactional(ProceedingJoinPoint proceedingJoinPoint) throws NoSuchMethodException {
        Signature signature = proceedingJoinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method realMethod = proceedingJoinPoint.getTarget().getClass()
                .getDeclaredMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        return realMethod.isAnnotationPresent(Transactional.class);
    }
}
​

二、接口及实现

package com.aop.service;
​
public interface AopService {
    BizReturn create(); // 所有借口返回BizReturn,自定义,可以定义成其他的,根据需要在AOP中捕获自定义异常,处理已定义异常,回滚事务
}
​
​
package com.aop.service.impl;
import com.aop.service.AopService;
import com.tf56.core.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
​
@Service("aopService")
@Slf4j
public class AopServiceImpl implements AopService {
    
    @Override
    @Transactional
    public BizReturn create() {
        log.info("create start.");
        throw new BizException("数据不存在...");
    }
}
​

三、单测使用示例

    @Autowired
    private AopService aopService;
    
    @Test
    public void createTest() {
        String s = aopService.create();
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值