aop切入日志

  1. ioc和aop是spring的两大特征,ioc为我们提供了一个ioc容器,容器帮我们去创建对象,不用手动创建,下面是注解aop的操作步骤。
  2. 首先自己 定义注解LogAnnotation,注意加上三个注解
    package com.mszlu.blog.common.aop;
    
    import java.lang.annotation.*;
    
    /**
     * 日志注解
     */
     //ElementType.TYPE代表可以放在类上面  method代表可以放在方法上
    @Target(ElementType.METHOD)  //表示放到方法上,一般放到controller方法上
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface LogAnnotation {
    
        String module() default ""; //注解的两个参数
    
        String operation() default "";
    }
    
    

  3. 在需要日志的方法上进行写入上边定义的日志注解

  4. @PostMapping
    @LogAnnotation(module="文章",operation="获取文章列表") //这里的参数主要是在后边的around方法中调用这两个变量为日志的内容
    public Result listArticle(@RequestBody PageParams pageParams){
        return articleService.listArticle(pageParams);
    }

    5.编写切面类,完成日志调用输出的操作

    @Component
    @Aspect //切面 
    @Slf4j //与log4j区别是:这个可以实现参数引用  eg:("params:{}",params)
    ({aaa},"这是前边的参数引用,不用写具体的格式")
    public class LogAspect{
    
    @Pointcut("@annotation(com.ryf.blog.common.aop.LogAnnotation))//切点为使用这个注解的所有方法
    public void pu(){}
    
    @Around("pt()")  //在执行方法前后调用Advice,这是最常用的方法,相当于@Before和@AfterReturning全部做的事儿
    public Object log(ProceedingJoinPoint point) throws Throwable{
        long beginTime = System.currentTimeMillis();
        Object result = point.proced();//当我们执行完切面代码之后,还有继续处理业务相关的代码。proceed()方法会继续执行业务代码,并且其返回值,就是业务处理完成之后的返回值。
    //下边的时间为 执行完业务方法后的时间减去 开始的时间
            long time = System.currentTimeMillis() - beginTime;
            //保存日志
            recordLog(point, time); //调用下边的具体实现日志的方法
            return result;
    
        }
    
        private void recordLog(ProceedingJoinPoint joinPoint, long time) {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            LogAnnotation logAnnotation = method.getAnnotation(LogAnnotation.class);
            //获得这个注解类
            log.info("=====================log start================================");
            log.info("module:{}",logAnnotation.module()); //获得controller方法上注解的参数
            log.info("operation:{}",logAnnotation.operation());
    
            //请求的方法名
            String className = joinPoint.getTarget().getClass().getName();
            String methodName = signature.getName();
            log.info("request method:{}",className + "." + methodName + "()");
    
    //        //请求的参数
            Object[] args = joinPoint.getArgs();
            String params = JSON.toJSONString(args[0]);
            log.info("params:{}",params);
    
            //获取request 设置IP地址
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            log.info("ip:{}", IpUtils.getIpAddr(request));
    
    
            log.info("excute time : {} ms",time);
            log.info("=====================log end================================");
        }
    
    
    
    
    }
    

    6.下边两个工具类

    package com.mszlu.blog.utils;
    
    import org.springframework.web.context.request.RequestContextHolder;
    import org.springframework.web.context.request.ServletRequestAttributes;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * HttpServletRequest
     *
     */
    public class HttpContextUtils {
    
        public static HttpServletRequest getHttpServletRequest() {
            return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        }
    
    }
    
    
    package com.mszlu.blog.utils;
    
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.lang3.StringUtils;
    
    import javax.servlet.http.HttpServletRequest;
    
    /**
     * 获取Ip
     *
     */
    @Slf4j
    public class IpUtils {
    
        /**
         * 获取IP地址
         * <p>
         * 使用Nginx等反向代理软件, 则不能通过request.getRemoteAddr()获取IP地址
         * 如果使用了多级反向代理的话,X-Forwarded-For的值并不止一个,而是一串IP地址,X-Forwarded-For中第一个非unknown的有效IP字符串,则为真实IP地址
         */
        public static String getIpAddr(HttpServletRequest request) {
            String ip = null, unknown = "unknown", seperator = ",";
            int maxLength = 15;
            try {
                ip = request.getHeader("x-forwarded-for");
                if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                    ip = request.getHeader("Proxy-Client-IP");
                }
                if (StringUtils.isEmpty(ip) || ip.length() == 0 || unknown.equalsIgnoreCase(ip)) {
                    ip = request.getHeader("WL-Proxy-Client-IP");
                }
                if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                    ip = request.getHeader("HTTP_CLIENT_IP");
                }
                if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                    ip = request.getHeader("HTTP_X_FORWARDED_FOR");
                }
                if (StringUtils.isEmpty(ip) || unknown.equalsIgnoreCase(ip)) {
                    ip = request.getRemoteAddr();
                }
            } catch (Exception e) {
                log.error("IpUtils ERROR ", e);
            }
    
            // 使用代理,则获取第一个IP地址
            if (StringUtils.isEmpty(ip) && ip.length() > maxLength) {
                int idx = ip.indexOf(seperator);
                if (idx > 0) {
                    ip = ip.substring(0, idx);
                }
            }
    
            return ip;
        }
    
        /**
         * 获取ip地址
         *
         * @return
         */
        public static String getIpAddr() {
            HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
            return getIpAddr(request);
        }
    }
    
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

戏子☜已入画@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值