Spring 利用Aop和注解 加入log日志

1. 导入AOP的包 


      <!-- aop aspect注解导包-->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.6</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>

2. springMVC的配置

<!--扫描,Controller类-->
	<context:component-scan base-package="com.JXWork"/>
	<aop:aspectj-autoproxy proxy-target-class="true" expose-proxy="true">
		<!-- 指定@Aspect类,支持正则表达式,符合该表达式的切面类才会被应用-->
		<aop:include name="annotationLogAspect"></aop:include>
	</aop:aspectj-autoproxy>
	<bean id="annotationLogAspect" class="com.JXWork.service.AopLog.AnnotationLogAspect"/>

3. 定义AnnotationLog注解

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 AnnotationLog {
    String name() default "";
}

4. 声明切面类

定义切点(PointCut),定义连接点(JoinPoint),在这个AnnotationLog注解标注的方法上加入日志切入点。

package com.train.annotation;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.*;
/**
 * @auther: TF12778 2022/8/25 10:36
 * @description:
 */
@Component
@Slf4j
@Aspect
public class LogAspect {

    @Pointcut("@annotation(com.train.annotation.AnnotationLog)")
    public void logPoint() {
    }

    @Before("logPoint()")
    public void doBefore(JoinPoint joinPoint) {

    }

    @After("logPoint()")
    public void doAfter(JoinPoint joinPoint) {

    }

    /**
     *  ProceedingJoinPoint对象是JoinPoint的子接口,该对象只用在@Around的切面方法中,
     *  添加了  Object proceed() throws Throwable //执行目标方法
     *         Object proceed(Object[] var1) throws Throwable //传入的新的参数去执行目标方法
     */
    @Around("logPoint()")
    public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable {

        //获取连接点的方法签名对象
        Signature signature = joinPoint.getSignature();
        if (!(signature instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }

        MethodSignature methodSignature = null;
        methodSignature = (MethodSignature) signature;

        // 获取连接点所在的目标对象类
        Class target = joinPoint.getTarget().getClass();
        Method method = target.getMethod(methodSignature.getName(), methodSignature.getParameterTypes());
        AnnotationLog annotationLog = method.getAnnotation(AnnotationLog.class);
        log.info("注解内容获取:" + annotationLog.name());

        // 获取连接点方法运行时的入参列表
        Object[] params = joinPoint.getArgs();
        Map<String, Object> paramMap = object2Map(params[0]); // 参数转换为map

        log.info("{}.{}方法请求入参:{}", target.getSimpleName(), method.getName(), JSON.toJSONString(paramMap));
        Object result = joinPoint.proceed();
        log.info("{}.{}方法执行结果:{}", target.getSimpleName(), method.getName(), JSON.toJSONString(result));

        return result;
    }

    /**
     * 实体对象转成Map
     * @param obj 实体对象
     * @return
     */
    public static Map<String, Object> object2Map(Object obj) {
        Map<String, Object> map = new HashMap<>();
        List<Field> fieldList = new ArrayList<>() ;
        if (obj == null) {
            return map;
        }
        Class clazz = obj.getClass();
        while (clazz != null) {
            fieldList.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        try {
            for (Field field : fieldList) {
                field.setAccessible(true);
                if (Objects.equals("serialVersionUID", field.getName()) ) {
                    continue;
                }
                map.put(field.getName(), field.get(obj));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }

}

5.  在具体方法上加入注解 @AnnotationLog

 @RequestMapping(value = "/selectCustomerList")
    @AnnotationLog(name = "打印执行结果")
    public List<jxzCustomer> selectCustomerList(jxzCustomer query) {
        List<jxzCustomer> list = customerService.selectList(query);

        return list;
    }

测试结果:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值