通用日志注解工具实现
主要用于:
1、基本方法的参数以及异常情况控制台打印。
2、支持针对不同接口进行持久化实现。
注解
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface OperationLog {
/**
* 这里注意:
* 1、这里的logClass参数为实现了IOperationLogInterface接口的类,不同的类会进行不同的日志处理操作
* 2、如果 logClass 为空则走默认实现
*
* @return IOperationLog 实现类的 class
*/
Class logClass() default OperationLogInterface.class;
//打印日志自定义内容
String logContent() default "";
}
切面处理
@Slf4j
@Aspect
@Component
@Order(value = 10) //设置切面的执行顺序(越小越先执行) 间接控制事务是否生效
public class LogAspect {
@Pointcut("execution(public * com.*.*..*.*(..))")
public void getMethods() {
}
// 指定注解
@Pointcut("@annotation(ljl.utils.annotation.OperationLog)")
public void withAnnotationMethods() {
}
@Before(value = "getMethods() && withAnnotationMethods()")
public void startLog(JoinPoint joinPoint) {
MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
//方法名
String declaringTypeName = methodSignature.getDeclaringTypeName();
/**
* 参数
*/
LinkedHashMap<String, Object> paramMap = this.setMap(joinPoint);
//获取注解实例
OperationLog annotation = methodSignature.getMethod().getAnnotation(OperationLog.class);
log.info("《startLog日志》{}-》包路径:{},方法名:{}, 参数:{}", annotation.logContent(), declaringTypeName, methodSignature.getMethod().getName(), paramMap);
}
@AfterReturning(value = "getMethods() && withAnnotationMethods()", returning="returnValue")
public void succeedLog(JoinPoint joinPoint, Object returnValue) {
MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
//获取注解实例
OperationLog annotation = methodSignature.getMethod().getAnnotation(OperationLog.class);
log.info("《succeedLog日志》 将调用{}类进行日志的保存", annotation.logClass());
Object bean = SpringUtils.getBean(annotation.logClass());
if (null != bean) {
if (bean instanceof IOperationLogInterface) {
//执行日志的实现逻辑
((IOperationLogInterface) bean).succeedOperationLog(this.setMap(joinPoint), returnValue, annotation.logContent());
log.info("《succeedLog日志》 执行完毕");
} else {
log.error("《succeedLog日志》 {}类不属于IOperationLogInterface的实现类", annotation.logClass());
}
}else {
log.error("《succeedLog日志》 {}类未被spring进行管理", annotation.logClass());
}
}
@AfterThrowing(value = "getMethods() && withAnnotationMethods()", throwing = "exception")
public void errorLog(JoinPoint joinPoint, Exception exception) {
MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
//获取注解实例
OperationLog annotation = methodSignature.getMethod().getAnnotation(OperationLog.class);
log.error("《errorLog日志》 将调用{}类进行日志的保存", annotation.logClass());
Object bean = SpringUtil.getBean(annotation.logClass());
if (null != bean) {
if (bean instanceof IOperationLogInterface) {
//执行日志的实现逻辑
((IOperationLogInterface) bean).errorOperationLog(this.setMap(joinPoint), exception, annotation.logContent());
}
}
}
public LinkedHashMap<String, Object> setMap(JoinPoint joinPoint) {
MethodSignature methodSignature = ((MethodSignature) joinPoint.getSignature());
//参数
Object[] params = joinPoint.getArgs();
/**
* 参数名
*/
String[] parameterNames = methodSignature.getParameterNames();
//将参数处理为 map
LinkedHashMap<String, Object> paramMap = new LinkedHashMap<>();
if (null != parameterNames && parameterNames.length > 0) {
for (int i = 0; i < parameterNames.length; i++) {
String parameterName = parameterNames[i];
paramMap.put(parameterName, params[i]);
}
}
return paramMap;
}
}
日志实现的基本接口(后面进行自定义实现时需要实现此接口)
public interface IOperationLogInterface {
Logger log = LoggerFactory.getLogger(IOperationLogInterface.class);
/**
* 方法进入前
* @param setMap
*/
void startOperationLog(LinkedHashMap<String, Object> setMap);
/**
* 接口调用成功的实现
*
* @param requestParam 请求参数
* @param responseParam 返回值
* @param logContent 注解上的logContent属性
*/
void succeedOperationLog(LinkedHashMap<String, Object> requestParam, Object responseParam, String logContent);
/**
* 接口调用失败的实现
*
* @param requestParam 请求参数
* @param exception 异常信息
* @param logContent 注解上的logContent属性
*/
void errorOperationLog(LinkedHashMap<String, Object> requestParam, Exception exception, String logContent);
/**
* 复制并创建对象
* 将源数据复制到新创建的目标对象中
*
* @param tClass 目标类的class
* @param sourceData 源数据
* @return
*/
default <T> T copyCreateObject(Object sourceData, Class<T> tClass) {
if (null == sourceData) {
return null;
}
return JSONObject.parseObject(JSONObject.toJSONString(sourceData), tClass);
}
/**
* 复制并创建集合
* 将源数据复制到新创建的目标对象中
*
* @param tClass 目标类的class
* @param sourceData 源数据
* @return
*/
default <T> List<T> copyCreateList(Object sourceData, Class<T> tClass) {
if (null == sourceData) {
return null;
}
return JSONArray.parseArray(JSONObject.toJSONString(sourceData), tClass);
}
}
默认实现
@Component
public class OperationLogInterface implements IOperationLogInterface {
/**
* 成功
*
* @param requestParam 请求参数
* @param responseParam 返回值
* @param logContent 注解上的logContent属性
*/
@Override
public void succeedOperationLog(LinkedHashMap<String, Object> requestParam, Object responseParam, String logContent) {
log.info("成功日志默认实现执行,参数为:{}。返回值:{}。注解的logContent属性:{}", paramMap, returnValue, logContent);
}
/**
* 异常时执行
*
* @param requestParam 请求参数
* @param exception 异常信息
* @param logContent 注解上的logContent属性
*/
@Override
public void errorOperationLog(LinkedHashMap<String, Object> requestParam, Exception exception, String logContent) {
log.error("异常日志默认实现执行,参数为:{}", paramMap);
}
}
使用样例
//注意这种则使用默认日志处理类 OperationLogInterface
@OperationLog(logContent = "这里测试一下")
//这样自定义处理类
@OperationLog(logContent = "这里测试一下", logClass = Test.class)
@GetMapping(value = "/bigType/all")
@ApiOperation(httpMethod = "GET", value = "测试")
public Wrapper<EncyclopediaVaccine> bigType() {
return WrapMapper.ok(vaccineInfoService.encyclopediaVaccineBigTypes(getLoginAuthDmxcxDto()));
}
@Component
public class Test implements IOperationLogInterface {
@Override
public void succeedOperationLog(LinkedHashMap<String, Object> paramMap, Object returnValue) {
log.info("成功日志实现执行,参数为:{}。返回值:{}", paramMap, returnValue);
}
@Override
public void errorOperationLog(LinkedHashMap<String, Object> paramMap) {
log.error("异常日志实现执行,参数为:{}", paramMap);
}
}