springboot 自定义注解,Log类注解

博客围绕切面日志注解展开,作者在学习他人自定义注解的过程中进行解析。日志服务采用@Slf4j 作为支持,还定义了 Log 自定义注解及枚举类型,同时提到了 @Around 环绕增强。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 切面日志注解

最近看别人的自定义注解还是很优秀,再次一边学习一边解析一下

日志服务用的@Slf4j 作为服务支持

1.1 Log自定义注解

@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface AroundLog {
    AroundLogMethod method() default AroundLogMethod.DEFAULT;
    boolean pre() default true;
    boolean post() default false;
}

还定义了一个枚举类型来

public enum  AroundLogMethod {
    GET,
    POST,
    DEFAULT
}

1.2  @Around

环绕增强,相当于MethodInterceptor.

*     @Before: 标识一个前置增强方法,相当于BeforeAdvice的功能.
*     @After: final增强,不管是抛出异常或者正常退出都会执行.
*     @AfterReturning: 后置增强,似于AfterReturningAdvice, 方法正常退出时执行.
*     @AfterThrowing: 异常抛出增强,相当于ThrowsAdvice.
*     @Around: 环绕增强,相当于MethodInterceptor.

1.3 

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.time.DateFormatUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

@Aspect
@Component
public class AccessLogAscept {

    private static final List<String> ignoreUri = Stream.of("***", "***").collect(Collectors.toList());

    private static final Logger logger = LoggerFactory.getLogger("access");

    @AfterReturning(value = "@annotation(org.springframework.web.bind.annotation.PostMapping)", returning="result")
    public void afterReturning(JoinPoint point, Object result){
        if(result instanceof RespResult){
            accessLog((RespResult)result);
        }else{
            accessLog(new RespResult(RespCode.SUCC, ""));
        }
    }

    @AfterThrowing(value = "@annotation(org.springframework.web.bind.annotation.PostMapping)", throwing="ex")
    public void afterReturning(JoinPoint point, Exception ex){
        RespResult respResult = JsonUtils.fromJson(ex.getMessage(), RespResult.class);
        if(null == respResult){
            accessLog(new RespResult(-1, ex.getMessage() , ""));
        }else {
            accessLog(respResult);
        }
    }

    private void accessLog(RespResult result) {
        ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String uri = request.getRequestURI();
        if(ignoreUri.contains(uri)){ //过滤掉某些接口的日志
            return;
        }
        long inTimeMillis = MyThreadLocal.getInTimeMillis();
        String time = DateFormatUtils.format(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss.SSS");
        String ip = getIpAddr(request);
        String userName = null==MyThreadLocal.getUserInfo()?"":MyThreadLocal.getUserInfo().getUserName();
        String globalRequestId = MyThreadLocal.getCurGlobalRequestId();
        long diff = System.currentTimeMillis() - inTimeMillis;
        int rtn = result.getCode();
        String msg = result.getMsg();
        logger.warn(String.format("%s;%s;%s;%s;%s;%s;%s;%s",time, nonReplace(ip), nonReplace(userName), nonReplace(globalRequestId),
                nonReplace(uri), diff, rtn, msg));
    }

    private String nonReplace(String s) {
        return StringUtils.isBlank(s) ? "-" : s;
    }

    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值,第一个ip才是真实ip
            if( ip.indexOf(",")!=-1 ){
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值