zoukankan      html  css  js  c++  java
  • 【springboot】AOP(注解版)使用例子

    1、简单使用,打印访问方法时,进入、方法全限定名称、参数索引位置、参数类型及内容(如果为null就只打印null)、正常/异常退出。

    1.1、定义注解用于切面

    package com.frame.annotation;
    
    
    import java.lang.annotation.*;
    
    /**
     * 方法日志注解
     *
     * @author lw
     * @version V1.0
     * @Title: MothodLog.java
     * @Package com.frame.base.annotation
     * @Description: 注解在被访问的方法时,打印类名、方法名、参数。方便上线排错
     * @date 2019年12月23日 下午3:21:33
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface MothodLogPrint {
    }

    1.2、切面类

    package com.frame.sys.aop;
    
    import com.frame.annotation.MothodLogPrint;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import java.util.Collection;
    import java.util.Map;
    
    /**
     * MothodLogPrintAspect利用spring的aop实现日志的打印
     *
     * @auther lw
     * @date 2019-12-24 15:32:33
     */
    @Aspect
    @Component
    public class MothodLogPrintAspect {
    
        private static final Logger logger = LoggerFactory.getLogger(MothodLogPrintAspect.class);
    
        @Around("@annotation(mothodLogPrint)")
        public Object advice(ProceedingJoinPoint joinPoint, MothodLogPrint mothodLogPrint){
            String className = joinPoint.getTarget().getClass().getName();
            String mothodName = joinPoint.getSignature().getName();
            logger.info(">>>>>>>>>进入,方法:[" + className + "." + mothodName + "]");
            Object[] args = joinPoint.getArgs();
            String mothodPropertion = getMothodPropertion(className, mothodName, args);
            logger.info(mothodPropertion);
            Object proceed = null;
            try {
                proceed = joinPoint.proceed();
                logger.info("<<<<<<<<<正常,退出方法:[" + className + "." + mothodName + "]");
            } catch (Throwable throwable) {
                logger.error(throwable.getMessage(), throwable);
                logger.info("<<<<<<<<<异常,退出方法:[" + className + "." + mothodName + "]");
            }
            return proceed;
        }
    
        /**
         * 获取方法和参数内容
         *
         * @param className 类名 非必填
         * @param mothodName 方法名 必填
         * @param agrs 参数列表
         * @return
         */
        public static String getMothodPropertion(String className, String mothodName, Object ... agrs) {
            StringBuilder sb = new StringBuilder();
            if(null != className) {
                sb.append("类名:[").append(className).append("]
    ");
            }
            sb.append("方法:[").append(mothodName).append("]");
            if(null != agrs) {
                for(int i = 0; i < agrs.length; i++) {
                    Object obj = agrs[i];
                    sb.append("
    参数索引:[").append(i).append("],");
                    if(null == obj) {
                        sb.append("为null");
                    } else {
                        sb.append("类型:[").append(obj.getClass().getName()).append("],");
                        if(obj instanceof Collection) {
                            Collection collection = (Collection)obj;
                            sb.append("长度:[").append(collection.size()).append("],内容:[").append(collection).append("]");
                        } else if(obj instanceof Map) {
                            Map map = (Map)obj;
                            sb.append("长度:[").append(map.size()).append("],内容:[").append(map).append("]");
                        } else if(obj.getClass().isArray()) {
                            Object[] objects = (Object[])obj;
                            sb.append("长度:[").append(objects.length).append("],内容:[").append(objects).append("]");
                        } else if(obj instanceof String) {
                            sb.append("内容:[").append(obj).append("]");
                        } else {
                            sb.append("内容:[").append(String.valueOf(obj)).append("]");
                        }
                    }
                }
            }
            return sb.toString();
        }
    
    }

    1.3、用于切面的例子

    com.frame.solr.service.SolrService#getByMap

    1.4、打印日记

    2、切面修改参数再访问

    2.1、注解

    package com.frame.annotation;
    
    
    import java.lang.annotation.*;
    
    /**
     * solr、db查询模式
     *
     * @author lw
     * @version V1.0
     * @Title: SolrOrDbStrategy.java
     * @Package com.frame.base.annotation
     * @Description: 注解在被访问的方法时,方式有个参数可根据solr还是db来进行查询
     * @date 2020年2月11日 下午4:21:33
     */
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface SolrOrDbStrategy {
    }

    2.2、切面类

    package com.frame.sys.aop;
    
    import com.frame.annotation.SolrOrDbStrategy;
    import com.frame.modules.dabis.archives.ArchivesConstant;
    import com.frame.solr.em.SolrCode;
    import com.frame.solr.service.SolrService;
    import com.frame.strategy.StrategySituation;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    
    /**
     * SolrOrDbStrategyAspect利用spring的aop实现solr查询异常时转db
     * 默认是用solr查询,如果solr断了就切换到mysql查询。如果是solr语句有问题则不切换
     *
     * @auther lw
     * @date 2020-2-11 16:20:33
     */
    @Aspect
    @Component
    public class SolrOrDbStrategyAspect {
    
        private static final Logger logger = LoggerFactory.getLogger(SolrOrDbStrategyAspect.class);
    
        @Autowired
        private SolrService solrService;
    
        @Autowired
        private StrategySituation strategySituation;
    
        @Around("@annotation(solrOrDbStrategy)")
        public Object advice(ProceedingJoinPoint joinPoint, SolrOrDbStrategy solrOrDbStrategy){
            Object[] args = joinPoint.getArgs();
            Object proceed = null;
            try {
                if (ArchivesConstant.queryType.SOLR.getValue().equals(StrategySituation.getTheCurrentStrategy())) {
                    proceed = joinPoint.proceed();
                    logger.info("使用solr查询");
                } else {
                    for (int i = 0; i < args.length; i++) {
                        Object obj = args[i];
                        if (ArchivesConstant.queryType.SOLR.getValue().equals(obj) || ArchivesConstant.queryType.DB.getValue().equals(obj)) {
                            // 修改参数
                            args[i] = ArchivesConstant.queryType.DB.getValue();
                            break;
                        }
                    }
                    // 修改参数后再执行方法
                    proceed = joinPoint.proceed(args);
                    logger.info("使用db查询");
                }
            } catch (Throwable throwable) {
                if (solrService.detectSolrConnection(SolrCode.ARCHIVES.getValue())) {
                    logger.error("solr连接正常,solr语句有误", throwable);
                } else {
                    for (int i = 0; i < args.length; i++) {
                        Object obj = args[i];
                        if (ArchivesConstant.queryType.SOLR.getValue().equals(obj) || ArchivesConstant.queryType.DB.getValue().equals(obj)) {
                            // 修改参数
                            args[i] = ArchivesConstant.queryType.DB.getValue();
                            break;
                        }
                    }
                    try {
                        // 修改参数后再执行方法
                        proceed = joinPoint.proceed(args);
                        logger.error("solr连接异常,转db查询");
                        strategySituation.switchState(ArchivesConstant.queryType.DB.getValue());
                    } catch (Throwable e) {
                        logger.error("db查询异常", e);
                    }
                }
            }
            return proceed;
        }
    
    }

    2.3、切入

    2.4、结果

    正常

    solr断了

     

    3、可根据类型处理

    3.1、注解需要type

     3.2、切面类根据不同type处理

    3.3、切入

     

  • 相关阅读:
    Android ADB批处理脚本
    【转载】SecureCRT配色推荐和永久设置
    【转载】Ubuntu中Source Insight的使用
    Ubuntu美化操作
    【转】数据线上的串联小电阻(图)
    VMware下利用ubuntu13.04建立嵌入式开发环境之三
    VMware下利用ubuntu13.04建立嵌入式开发环境之二
    VMware下利用ubuntu13.04建立嵌入式开发环境之一
    ubuntu 13.04 telnet 详细配置
    candence 知识积累4
  • 原文地址:https://www.cnblogs.com/xiaostudy/p/12336147.html
Copyright © 2011-2022 走看看