11.spring boot aop 日志

业务场景:pc端,登陆页面,登陆账户后,访问各个模块,每次访问和操作都记录日志.

1.开启aop,就一步.


    org.springframework.boot
    spring-boot-starter-aop

application.yml中下面这个设置默认开启

spring.aop.auto=true

2.增加一个自定义annotation

package com.yunchuang.config.annotation;

import java.lang.annotation.*;

/**
 * 日志
 *
 * @author 尹冬飞
 * @date 2015-07-02 15:43:26
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
public @interface Log {
    /**
     * 1.日志内容
     */
    String value();
}

3.定义切面类

package com.yunchuang.config.aspect;

import com.yunchuang.config.annotation.Log;
import com.yunchuang.console.user.domain.User;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
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 javax.servlet.http.HttpSession;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * aop切面日志
 *
 * @author 尹冬飞
 * @create 2017-05-02 14:16
 */
@Aspect
@Component
public class LogAspect {
    private Logger logger = LoggerFactory.getLogger(LogAspect.class);

    @Pointcut("execution(public * com.yunchuang.console.*.web..*.*(..))")
    public void consoleLog() {
    }

    @Before("consoleLog()")
    public void doBefore(JoinPoint joinPoint) throws Throwable {
        // 接收到请求,记录请求内容
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        //获取request
        HttpServletRequest request = attributes.getRequest();
        //获取session
        HttpSession session = request.getSession();
        //获取方法签名
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取方法
        Method method = signature.getMethod(); //获取被拦截的方法
        //获取自定义Log注解
        Log annotation = method.getAnnotation(Log.class);
        //如果有Log注解,则写入日志
        if (annotation != null) {
            //获取session里的用户对象
            User user = (User) session.getAttribute("loginUser");
            //获取用户名
            String name = user != null ? "[" + user.getNickname() + "]" : "";
            logger.info(name + "[" + annotation.value() + "][" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName() + "][" + Arrays.toString(joinPoint.getArgs()) + "][" + request.getRemoteAddr() + "]");
        }
    }

    @AfterReturning(returning = "ret", pointcut = "consoleLog()")
    public void doAfterReturning(Object ret) throws Throwable {
        // 处理完请求,返回内容
        //logger.info("RESPONSE : " + ret);
    }
}

这里关键的2个地方:
获取方法,就能获取自定义注解,就能获取里面的值

//获取方法签名
MethodSignature signature = (MethodSignature) joinPoint.getSignature();

获取请求内容就能获取request和session

// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

4.在controller的方法上增加自定义注解.

因为Log类里属性是value(),所以注解里不用写@Log(value="日志内容")

    @Log("日志内容")
    @GetMapping("/list")
    public String list() {
        return "console/user/list";
    }

你可能感兴趣的:(11.spring boot aop 日志)