方法级别的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实现
目录结构
日志注解类:
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、基于注解实现
目录结构
日志注解类
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
下一篇: Mybatisplus中的分页查询