欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

方法级别的AOP日志

程序员文章站 2022-03-19 16:06:07
本文章主要是基于方法级别的aop实现,即在方法上添加注解,实现aop的日志落表目录结构日志注解类:package com.aopmethod.transaction;import java.lang.annotation.*;@Target({ElementType.METHOD,ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface LoggerAspect...

本文章主要是基于方法级别的aop实现,即在方法上添加注解,实现aop的日志落表

1、基于xml实现

目录结构

方法级别的AOP日志

日志注解类:

package com.aopmethod.transaction;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoggerAspect {

    /** 要执行的操作类型比如:比如接收接口,发送接口 **/
    String operationType() default "";

    /** 要执行的具体操作比如:方法名称 **/
    String operationName() default "";
}

日志实现类:

package com.aopmethod.transaction;

import com.alibaba.fastjson.JSON;
import com.ouyeel.platform.components.rzcore.foundation.dao.sjd.InterfaceInstructionsMapper;
import com.ouyeel.platform.components.rzcore.foundation.model.sjd.InterfaceInstructionsWithBLOBs;
import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

public class ArchivesLogAspect {

    private final static Logger logger = LoggerFactory.getLogger(ArchivesLogAspect.class);

    @Resource
    private InterfaceInstructionsMapper interfaceInstructionsMapper;
    /**
     * 注解到Method ,进行日志管理
     * 返回通知(在方法正常结束执行的代码)
     * @param
     * joinPoint --获取方法基础信息
     * result --方法返回值
     */
    public void afterReturnMethod(JoinPoint joinPoint, Object result){

        String targetName = joinPoint.getTarget().getClass().getName();     //类名
        String methodName = joinPoint.getSignature().getName();             //方法名
        Object[] arguments = joinPoint.getArgs();                           //参数
        logger.info("类名:"+targetName+",方法名:"+methodName);
        Class targetClass = null;
        try {
            targetClass = Class.forName(targetName);            //加载类
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] methods = targetClass.getMethods();            //加载方法
        String operationName = "";              //接口类别
        String operationType = "";              //发送或者接收接口
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs!=null&&clazzs.length == arguments.length&&method.getAnnotation(LoggerAspect.class)!=null) {
                    operationName = method.getAnnotation(LoggerAspect.class).operationName();
                    operationType = method.getAnnotation(LoggerAspect.class).operationType();
                    break;
                }
            }
        }
        if ("1".equals(operationType)) {       //发送接口
            for (Object prams : arguments) {//方法入参
                logger.info("发送接口---1");
                Map<String ,Object> pramsMap = (Map<String ,Object>)prams;
                InterfaceInstructionsWithBLOBs iLog = new InterfaceInstructionsWithBLOBs();
                iLog.setId(UUID.randomUUID().toString().replaceAll("-", ""));
                iLog.setCreateDate(new Date());
                iLog.setBusinessId(pramsMap.get("applicationId").toString());
                iLog.setBusinessAmount(new BigDecimal("100"));
                iLog.setInstructionType("0");
                iLog.setReceiveFunction(targetName+"."+methodName);
                iLog.setInterfaceDesc("aop日志数据落表");
                iLog.setReceiveMessage(JSON.toJSONString(prams));//方法入参
                iLog.setFeedbackMessage(JSON.toJSONString(result));//方法返回
                interfaceInstructionsMapper.insert(iLog);
            }
        } else if ("0".equals(operationType)) {       //接收接口
            logger.info("接收接口---0");
            for (Object prams : arguments) {
                logger.info("prams:"+JSON.toJSONString(prams));
            }
        } else {        //只有声明接口类别的方法才记录接口日志
            logger.info("匹配注解类型失败");
        }
        logger.info("aop日志记录成功");
    }
}

配置文件

<!--配置Aop-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
<!--指明 注解 所在包,并扫描其中的注解-->
    <context:component-scan base-package="com.*"/>
<!--将日志类注入到bean中。-->
    <bean id="logAspect" class="com.aopmethod.transaction.ArchivesLogAspect"></bean>
    <aop:config>
        <!--调用日志类-->
        <aop:aspect id="LogAspect" ref="logAspect">
            <!--配置在controller包下所有的类在调用之前都会被拦截-->
            <aop:pointcut id="log"
                          expression="execution(public * com.aopmethod.service.*.*(..))"/>
            <aop:after-returning method="afterReturnMethod" pointcut-ref="log" returning="result"/>
        </aop:aspect>
    </aop:config>

测试方法

package com.aopmethod.service.impl;

import com.aopmethod.service.TestService;
import com.aopmethod.transaction.LoggerAspect;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

@Service
public class TestServiceImpl implements TestService {

    @Override
    @LoggerAspect(operationName = "aopInsertLog",operationType = "1")
    public Map aopInsertLog(Map paramMap){
        logger.info("进入--aopInsertLog--方法");
        Map<String,String> resMap = new HashMap<>(2);
        resMap.put("result","1");
        resMap.put("msg","aop日志插入成功");
        return  resMap;
    }
}

2、基于注解实现

目录结构

方法级别的AOP日志

日志注解类

package com.annoaop.transaction;

import java.lang.annotation.*;

@Target({ElementType.METHOD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AnnoAop {

    /** 要执行的操作类型比如:add操作 **/
    String operationType() default "";

    /** 要执行的具体操作比如:添加用户 **/
    String operationName() default "";

}

日志实现类

package com.annoaop.transaction;

import net.sf.json.JSONObject;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;

@Aspect
@Component
public class ArchivesAnnoAop {

    private static final Logger logger = LoggerFactory.getLogger(ArchivesAnnoAop.class);

    /**后置通知*/
    @AfterReturning(value = "@annotation(com.annoaop.transaction.AnnoAop)")
    public void afterReturning(JoinPoint joinPoint){
        logger.info("afterReturning:"+joinPoint.getTarget()+","+joinPoint.getSignature().getName());
        String targetName = joinPoint.getTarget().getClass().getName();     //类名
        String methodName = joinPoint.getSignature().getName();             //方法名
        Object[] arguments = joinPoint.getArgs();                           //参数
        logger.info("类名:"+targetName+",方法名:"+methodName);
        Class targetClass = null;
        try {
            targetClass = Class.forName(targetName);            //加载类
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Method[] methods = targetClass.getMethods();            //加载方法
        String operationName = "";              //接口类别
        String operationType = "";              //发送或者接收接口
        for (Method method : methods) {
            if (method.getName().equals(methodName)) {
                Class[] clazzs = method.getParameterTypes();
                if (clazzs!=null&&clazzs.length == arguments.length&&method.getAnnotation(AnnoAop.class)!=null) {
                    operationName = method.getAnnotation(AnnoAop.class).operationName();
                    operationType = method.getAnnotation(AnnoAop.class).operationType();
                    break;
                }
            }
        }
        logger.info("operationName:"+operationName+",operationType:"+operationType);
        if ("1".equals(operationType)) {       //发送接口
            logger.info("发送接口---1");
            for (Object prams : arguments) {//方法入参
                logger.info("prams:"+JSONObject.fromObject(prams).toString());
            }
            //此处可进行日志处理--eg:日志落表等操作
        } else if ("0".equals(operationType)) {       //接收接口
            logger.info("接收接口---0");
            for (Object prams : arguments) {
                logger.info("prams:"+JSONObject.fromObject(prams).toString());
            }
        } else {        //只有声明接口类别的方法才记录接口日志
            logger.info("匹配注解类型失败");
        }
        logger.info("aop日志记录成功");
    }

}

配置文件

<!--配置Aop-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>
<!--指明 注解 所在包,并扫描其中的注解-->
    <context:component-scan base-package="com.*"/>

测试类

package com.annoaop.service.impl;

import com.annoaop.service.AnnoAopService;
import com.annoaop.transaction.AnnoAop;
import org.springframework.stereotype.Service;
import java.util.HashMap;
import java.util.Map;

@Service
public class AnnoAopServiceImpl implements AnnoAopService {

    @AnnoAop(operationName = "annoAop",operationType = "1")
    @Override
    public Map annoAop(Map<String ,Object>map){
        System.out.println("into--annoAop");
        return null;
    }
}

 

即可根据注解实现日志落表

说明:

以上注解只可在 serviceImpl中使用,如果要在controller层中使用,需在spring-mvc.xml中添加aop标签:

<!--配置Aop-->
    <aop:aspectj-autoproxy proxy-target-class="true"/>

 

本文地址:https://blog.csdn.net/weixin_42179326/article/details/111856523

相关标签: 优雅代码 aop