自定义注解+AOP监视接口任务心得

一 ,自定义注解

先上源码:

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.TYPE, ElementType.METHOD})
public @interface Surveillance {
    boolean value() default false;
    String remarks() default StringUtils.EMPTY;
}

1.自定义注解的命名格式:
public @interface 注解名称{}

2.@Inherited
被当前注解修饰的类,会自动继承至子类

3.@Retention(RetentionPolicy.RUNTIME)
标识运行期 运行。一般情况,默认使用该情形

4.@Target

标识 注解的使用范围
ElementType.TYPE —》类,接口
ElementType.METHOD —》方法

5.自定义注解的参数格式:

a.类型 + 方法名 +()+ default + 默认值
() 不可省略,这是注解作用域的命名规则

b.类型 + 方法名 +()
在注解上,没有默认值 则必须赋值
例如:
@zhujie(name = "mingzi",age = 23)
public class student(){}

二,AOP切面监视接口参数

这次任务的目标是,将指定接口方法调用进行监视,并额外对添加注解的接口进行监视。

将 地址,接口,参数,用户名 等等记录至数据库中

源码:

/**
 * @Author leejiangyo
 * @Date: 2021/5/6 10:39
 */

@Aspect
@Component
public class LoggerAop {
    private static LogFilter logFilter = new LogFilter();
    //本地日志记录对象
    private static final Logger logger = LoggerFactory.getLogger(LoggerAop.class);
    private static Class<Surveillance> surveillanceClass = Surveillance.class;
    private static List<String> defaultMethodList = new ArrayList();
    private static boolean flagA;
    private static boolean flagB;
    private static boolean flagC;
    private static final String CREATECN = "新增方法";
    private static final String UPDATECN = "更新方法";
    private static final String DELETECN = "删除方法";
    private static final String CREATE = "create";
    private static final String CREATE_BATCH = "createBatch";
    private static final String UPDATE = "update";
    private static final String UPDATE_INBATCH = "updateInBatch";
    private static final String MULTI_DELETE = "multiDelete";
    private static final String DELETE = "delete";

    static {
        defaultMethodList.add(CREATE);
        defaultMethodList.add(CREATE_BATCH);
        defaultMethodList.add(UPDATE);
        defaultMethodList.add(UPDATE_INBATCH);
        defaultMethodList.add(MULTI_DELETE);
        defaultMethodList.add(DELETE);
    }

    //controller切点
    @Pointcut("execution(* com..*.*Controller.*(..))")
    public void pointCut() {
    }

    @Around(value = "pointCut()")
    public Object doAroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //获取request对象
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        //获取请求方法(全限定名)
//        String methodName = proceedingJoinPoint.getTarget().getClass().getName() + "." + proceedingJoinPoint.getSignature().getName();
        //获取方法名(简写)
        String methodName = proceedingJoinPoint.getSignature().getName();
        //获取方法执行返回值
        Object returningValue = proceedingJoinPoint.proceed();
        /* 类名 */
        String targetObject = proceedingJoinPoint.getTarget().getClass().getName();
        Object[] args = proceedingJoinPoint.getArgs();
        Class<?> targetClass = Class.forName(targetObject);
        Method[] methods = targetClass.getMethods();

        flagA = false;
        flagB = false;
        flagC = false;
        String remarks = null;
        //condition a;default
        if (verifyDefaultMethodList(methodName)) {
            flagA = true;
        } else {
            //condition b; when value is true, all methods in surveillance;
            Surveillance annotation = targetClass.getAnnotation(surveillanceClass);
            if (targetClass.isAnnotationPresent(surveillanceClass) && annotation.value()) {
                flagB = true;
            }
        }
        //condition c; when surveillance on the top of method
        Method[] methods3 = targetClass.getMethods();
        for (Method m : methods3) {
            if (m.isAnnotationPresent(surveillanceClass)) {
                Surveillance an = m.getAnnotation(surveillanceClass);
                remarks = an.remarks();
                flagC = true;
                break;
            }
        }
        if (!(flagA || flagB || flagC)) {
            return returningValue;
        }

        /**
         * 遍历方法 获取能与方法名相同且请求参数个数也相同的方法
         */
        int flag = 0;
        Object[] argss = new Object[args.length];
        for (Method method : methods) {
            if (!method.getName().equals(methodName)) {
                continue;
            }

            Class<?>[] classes = method.getParameterTypes();

            if (classes.length != args.length) {
                continue;
            }

            for (int index = 0; index < classes.length; index++) {
                if (args[index] instanceof HttpServletRequest
                        || args[index] instanceof HttpServletResponse) {
                    continue;
                }
                argss[flag++] = args[index];
            }
        }
        List<Object> list = Arrays.asList(argss);
        List<Object> list2 = null;
        if (CollectionUtils.isNotEmpty(list)) {
            list2 = new ArrayList<>();
            for (int i = 0, length = list.size(); i < length; i++) {
                if (list.get(i) != null) {
                    list2.add(list.get(i));
                }
            }
        }
        String params = JSONArray.toJSONString(list2);
        //获取request 的内容参数
        StringBuilder strParam = new StringBuilder(100);
        Map<String, String[]> params2 = request.getParameterMap();
        if (params2 != null) {
            strParam.append("?");
            boolean nextParam = false;
            Iterator iter = params2.keySet().iterator();

            while (iter.hasNext()) {
                if (nextParam) {
                    strParam.append("&");
                } else {
                    nextParam = true;
                }

                String key = (String) iter.next();
                strParam.append(key).append("=");
                strParam.append(request.getParameter(key));
            }
        }

        //返回值转为json数组
//        String returnJsonValue = JSONArray.toJSONString(returningValue);
        StringBuffer requestURL = request.getRequestURL();

        logger.info("请求ip地址:{" + requestURL + "}," +
                "请求参数:{" + strParam.append(params) + "}");
        //将记录存入数据库 sys_common_log
        SysCommonLogService logService = ContextHolder.getBean(SysCommonLogService.class);
        SysCommonLog log = new SysCommonLog();
        ShiroUser su = ContextUtils.getCurrentUser();
        if (su != null) {
            UserService service = ContextHolder.getBean(UserService.class);
            User user = service.get(su.getUserId());
            HumanService humanService = ContextHolder.getBean(HumanService.class);
            Human human = humanService.get(su.getHumanId());
            log.setUserName(user == null ? null : user.getUserName());
            log.setTenantId(su.getFactTenantId());
            log.setBranchId(su.getFactBranchId());
            log.setUserCaption(human == null ? null : human.getName());
            log.setHumanId(su.getHumanId());
            log.setCreatedBy(su.getHumanId());
        }
        log.setSaasId(TenantUtils.getSaasId());
        log.setOperName(requestURL.toString());
        log.setOperIp(NetworkUtil.getIpAddress(request));
        log.setOperContent(strParam.append("--").append(params).toString());
        log.setClientType(EndConstants.COMMON_LOG_OPR);//操作日志类型
        log.setOperCaption(remarksTranslate(remarks, flagA, flagC, methodName));
        logService.save(log);
        return returningValue;
    }

    /**
     * methodName is current methodName.
     * check if this exist in DefaultMethodList
     *
     * @param methodName
     * @Author leejiangyo
     * @Date: 2021-05-12 11:21:58
     */
    private boolean verifyDefaultMethodList(String methodName) {
        for (String str : defaultMethodList) {
            if (methodName.equals(str)) {
                return true;
            }
        }
        return false;
    }

    private String remarksTranslate(String str, boolean flagA, boolean flagC, String methodName) {
        if (flagA && !flagC) {
            if (methodName.equals(CREATE) || methodName.equals(CREATE_BATCH)) {
                return CREATECN;
            } else if (methodName.equals(UPDATE) || methodName.equals(UPDATE_INBATCH)) {
                return UPDATECN;
            } else if (methodName.equals(DELETE) || methodName.equals(MULTI_DELETE)) {
                return DELETECN;
            }
        } else if (flagC) {
            return str;
        }
        return StringUtils.EMPTY;
    }

}

代码有不足之处,还请看官多多指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值