zoukankan      html  css  js  c++  java
  • 面向注解的切面实现

    1.

    package com.g2.order.server.annotation;
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface LogAttribute {
    }

    2.

    package com.g2.order.server.annotation;
    
    
    import java.lang.annotation.ElementType;
    import java.lang.annotation.Retention;
    import java.lang.annotation.RetentionPolicy;
    import java.lang.annotation.Target;
    
    
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MaskLogAttribute {
        /**
         * 正则表达式,匹配到的将被转换为 ****
         * @return
         */
        String value() default "";
    }

    3.新建切面

    package com.g2.order.server.aspect;
    
    import com.g2.order.server.annotation.LogAttribute;
    import com.g2.order.server.annotation.MaskLogAttribute;
    
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.Around;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Pointcut;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.EnableAspectJAutoProxy;
    import org.springframework.core.annotation.Order;
    import org.springframework.stereotype.Component;
    import org.springside.modules.utils.text.JsonMapper;
    
    import java.lang.reflect.Method;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    //开启AspectJ 自动代理模式,如果不填proxyTargetClass=true,默认为false,
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    @Component
    @Aspect
    @Order(100)
    public class AnnotationLogAspectConfig {
        private static Logger logger = LoggerFactory.getLogger(AnnotationLogAspectConfig.class);
    
        @Pointcut("@annotation(com.g2.order.server.annotation.LogAttribute)")
        public void logPointcut() {
    
        }
    
        @Pointcut("@annotation(com.g2.order.server.annotation.MaskLogAttribute)")
        public void maskLogPointcut() {
    
        }
    
        @Around("maskLogPointcut() || logPointcut()")
        public Object handleControllerMethod(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            System.out.println("进入日志切面");
    
            //获取controller对应的方法.
            org.aspectj.lang.reflect.MethodSignature methodSignature = (org.aspectj.lang.reflect.MethodSignature) proceedingJoinPoint.getSignature();
            //获取方法所在的类(controller)
            Class beanType = methodSignature.getDeclaringType();
            //获取方法
            Method method = methodSignature.getMethod();
    
            String input, output;
    
            //获取方法参数列表(无需处理讨厌的流了)
            Object[] args = proceedingJoinPoint.getArgs();
            if (args.length == 0) {
                input = "(null)";
            } else {
                input = JsonMapper.INSTANCE.toJson(args[0]);
            }
    
            Object obj = proceedingJoinPoint.proceed();
            //获取返回值的类型,与 Method.getReturnType()一致
            output = JsonMapper.INSTANCE.toJson(obj);
            if (method.isAnnotationPresent(MaskLogAttribute.class)) {
                MaskLogAttribute maskLogAttribute = method.getAnnotation(MaskLogAttribute.class);
                String expr = maskLogAttribute.value();
                Pattern exprPattern = Pattern.compile(expr);
                Matcher m = exprPattern.matcher(input);
                input = m.replaceAll("****");
                m = exprPattern.matcher(output);
                output = m.replaceAll("****");
            }
    
            logger.info("类{}的方法{}的 输入参数为:{},输出参数为:{}", method.getDeclaringClass().getCanonicalName(), method.getName(),
                    input, output);
            return obj;
        }
    }

    5.controller类

    package com.g2.order.server.controller;
    
    import com.g2.order.dao.mapper.user.UserMapper;
    import com.g2.order.server.annotation.MaskLogAttribute;
    import com.g2.order.server.vo.user.UserLoginReq;
    import com.g2.order.dao.model.user.UserDao;
    import com.g2.order.server.vo.user.UserLoginResp;
    import com.g2.order.server.vo.user.UserModel;
    
    import io.swagger.annotations.Api;
    import io.swagger.annotations.ApiOperation;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.MediaType;
    import org.springframework.web.bind.annotation.*;
    
    @Api(value = "HomeController", description = "用户登录登出接口")
    @RestController
    @RequestMapping("/home")
    public class HomeController {
        private static Logger logger = LoggerFactory.getLogger(HomeController.class);
        @Autowired
        private UserMapper userMapper;
    
        @ApiOperation(value = "用户登录", notes = "用户登录接口")
        @RequestMapping(value = "/login",
                method = RequestMethod.POST,
                consumes = MediaType.APPLICATION_JSON_VALUE,
                produces = MediaType.APPLICATION_JSON_VALUE)
        @ResponseBody
        @MaskLogAttribute("\d{3}")
        public UserLoginResp login(@RequestBody UserLoginReq req) {
            logger.info("进入登陆业务");
            UserDao userDao = userMapper.getById(1);
            UserModel userModel = new UserModel();
            userModel.setRoleId(123);
            userModel.setUserId(Integer.toString(userDao.getUserId()));
            return new UserLoginResp(userModel);
        }
    }

    6.启动springboot

    package com.g2.order.server;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.web.servlet.ServletComponentScan;
    
    /**
     * 程序入口
     */
    @SpringBootApplication
    @ServletComponentScan
    public class App {
        public static void main(String[] args) {
            SpringApplication.run(App.class, args);
        }
    }

    7.调用

    http://127.0.0.1:88/home/login
    
    Post
    
    {
        "userId":"123","password":"123444"
    }

    8.输出

    2018-09-26 09:25:55.047  INFO 16716 --- [p-nio-88-exec-1] c.g.o.s.a.AnnotationLogAspectConfig      : 类com.g2.order.server.controller.HomeController的方法login的 输入参数为:{"corId":null,"userId":"****","password":"********"},输出参数为:{"success":true,"errorMessage":"","payload":{"userId":"1","roleName":null,"roleId":****}}
  • 相关阅读:
    springMVC 是单例还是的多例的?
    js如何获取数字占的位数~
    java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
    数据挖掘基本概念讲解
    js如何判断小数点后有几位
    volotile关键字的内存可见性及重排序
    上传文件multipart form-data boundary 说明
    vi 调到第一行和最后一行
    linux监控平台搭建-磁盘
    Guava Cache 参数配置说明
  • 原文地址:https://www.cnblogs.com/zhshlimi/p/9705175.html
Copyright © 2011-2022 走看看