Spring Boot使用AOP实现拦截某个方法

Posted 依米欧

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring Boot使用AOP实现拦截某个方法相关的知识,希望对你有一定的参考价值。

1、引入.jarl文件依赖

        <!-- Spring Boot Web 依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 从依赖信息里移除 Tomcat配置 -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

2、引入aop相关的jar

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>

3、编写Interceptor拦截类,两种方式实现

@Aspect
@Component
public class CallBackLogInterceptor {
    private Logger logger = LoggerFactory.getLogger(CallBackLogInterceptor.class);

    @Autowired
    private PlatformTransactionManager platformTransactionManager;//配置事务管理

    @Autowired
    private CallBackLogMapper callBackLogMapper;
    protected TransactionStatus startTx() {
        TransactionStatus transactionStatus = platformTransactionManager
                .getTransaction(new DefaultTransactionDefinition(TransactionDefinition.PROPAGATION_REQUIRES_NEW));
        return transactionStatus;
    }
    
    protected void commitTx(TransactionStatus transactionStatus){
        if(transactionStatus != null){
            platformTransactionManager.commit(transactionStatus);
        }
    }
    protected void rollbackTx(TransactionStatus transactionStatus){
        if (transactionStatus != null) {
            platformTransactionManager.rollback(transactionStatus);
        }
    }
    @AfterReturning(pointcut = "execution(* com.gcard.notify.sevice.impl.NotifyCashManager.notifyCash(..))&&args(notifyUrl, cashId, reqSn, callResult)", returning = "resultValue")
    public void handleInsertCallBackLog(String resultValue,String notifyUrl, String cashId, String reqSn, String callResult){
        try {
            logger.info(cashId);
            logger.info(resultValue);
            String result = StringUtils
                    .lessWord(resultValue, 1000 - 3);
            String type = SuperAppConstant.CASH_CALL_BACK_TYPE;
            int notifyStatus = SuperAppConstant.NOTIFY_STATUS_SUCCESS;
            addCallBackLog(cashId,notifyUrl,result,type,notifyStatus);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
    }
    @AfterThrowing(pointcut = "execution(* com.gcard.notify.sevice.impl.NotifyCashManager.notifyCash(..))&&args(notifyUrl, cashId, reqSn, callResult)", throwing="ex")
    public void handleUpdateCashAfterThrow(Throwable ex,String notifyUrl, String cashId, String reqSn, String callResult){
        try {
            logger.info(cashId);
            logger.info(ex.getMessage());
            String result = StringUtils
                    .lessWord(ex.getMessage(), 1000 - 3);
            String type = SuperAppConstant.CASH_CALL_BACK_TYPE;
            int notifyStatus = SuperAppConstant.NOTIFY_STATUS_FAIL;
            addCallBackLog(cashId, notifyUrl, result, type, notifyStatus);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }
}
    @Pointcut("execution(* com.gmall88.server.manager.superapp.SuperAppServerManager.addDo*(..))")
    public void addDo(){
        
    }
@AfterReturning(pointcut = "addDo()", returning = "resultValue")
    public void addDoPayAfterReturning(JoinPoint jp, Object resultValue) {
        try {
            Object[] parames = jp.getArgs();// 获取目标方法体参数
            String params = parseParames(parames); // 解析目标方法体的参数
            String className = jp.getTarget().getClass().toString();// 获取目标类名
            className = className.substring(className.indexOf("com"));
            logger.info("params" + params);
            String signature = jp.getSignature().toString();// 获取目标方法签名
            String methodName = signature.substring(signature.lastIndexOf(".") + 1, signature.indexOf("("));
            logger.info("methodName" + methodName);
            ReturnResult result = new ReturnResult();
            String msg= "";
            int code = -1;
            if(resultValue instanceof Map){
                Map map = (Map) resultValue;
                if(map.containsKey("errorMsg")){
                    msg= (String) map.get("errorMsg");
                }
            }else if(resultValue instanceof ReturnResult){
                result = (ReturnResult) resultValue;
                code = result.getCode();
                if(code != ReturnCodeType.SUCCESS.getCode()){
                    msg = result.getMessage();
                }
            }else{
                if(resultValue !=null){
                    msg = resultValue.toString();
                }
            }
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
    }

注意:拦截的方法要是一个bean调用才能生效,比如:拦截的notifyCash()方法,需要独立在一个类,然后被其他类调用

@Component
public class NotifyCashManager {
    private Logger logger = LoggerFactory.getLogger(getClass());
    
    public String notifyCash(String notifyUrl, String cashId, String reqSn, String callResult) throws Exception {
        String P = MD5.MD5Encode(cashId + "" + SuperAppConstant.NOTIFY_TOKEN);

        callResult = URLEncoder.encode(callResult, "UTF-8");
        String param = String.format("?Log_id=%s&P=%s&Req_Sn=%s&Cash_Result=%s", cashId, P, reqSn, callResult);
        String requestUrl = notifyUrl + param;
        logger.info("param=" + requestUrl);
        net.sf.json.JSONObject jsonObject = RF.httpsRequestJson(requestUrl, "POST", "");
        if (jsonObject == null) {
            String msg = null;
            msg = "Error to call notifyUrl.";
            logger.error(msg);
            throw new ExceptionVo(msg);
        } else {
            String msg = jsonObject.toString();
            logger.info("jsonObject=" + msg);
            if (jsonObject.containsKey("code")) {
                int code = jsonObject.getInt("code");
                if (code != SuperAppConstant.NOTIFY_RETURN_CODE_SUCCESS) {
                    String message = jsonObject.getString("message");
                    logger.error(message);
                    throw new ExceptionVo(message);
                }
            }
            return msg;
        }
    }
}

被调用:

@Autowired
private NotifyCashManager notifyCashManager;

notifyCashManager.notifyCash(notifyUrl, cashId, reqSn, callResult);//调用方式

 

以上是关于Spring Boot使用AOP实现拦截某个方法的主要内容,如果未能解决你的问题,请参考以下文章

Spring aop 拦截不到Dao

spring boot实现AOP登录拦截

Spring aop注解方式怎么获得执行了目标的某个方法?

Spring AOP不拦截从对象内部调用的方法

Spring AOP不拦截从对象内部调用的方法原因

Spring AOP不拦截从对象内部调用的方法原因