SpringBoot AOP自定义注解方式实现简单的日志管理
最近有个需求,需要实现对类方法的日志管理,涉及到其错误日志以及调用日志。在springboot实现,很简单,几乎没什么配置。
贴上代码:
import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.Date;
/**
* @author xxxx
* @description 日志管理 切点类
* @date 2019/4/4
*/
@Order(4)
@Aspect
@Component
public class OperateLogAspect {
private static Logger logger = Logger.getLogger(OperateLogAspect.class);
//日志保存数据库
@Resource
private OperateLogService operateLogService;
//切点
@Pointcut("execution (* com.*.plugin*..*.*.*(..))")
public void OperateLogAspect() {
}
/**
* 从进入方法到执行方法以及完成方法进行线程监控
* 环绕方法
* @param joinPoint
*/
@Around("OperateLogAspect()")
public Object Around(ProceedingJoinPoint joinPoint){
//拦截无Operatelog的方法
boolean op_type = Intercept(joinPoint);
long start = System.currentTimeMillis();
Object[] args = joinPoint.getArgs();
Object retProceed = "";
try {
logger.debug("==========开始执行方法环绕通知===============");
//获取
logger.debug("方法名:" + joinPoint.getTarget().getClass().getSimpleName());
//执行方法
retProceed = joinPoint.proceed();
//写入操作日志
if(op_type) {
insertOpLog(joinPoint);
}
} catch (Throwable e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw, true));
String str = sw.toString();
//写入错误日志
if(op_type) {
insertOpLogError(joinPoint,str);
}
logger.debug("错误日志: " + str);
e.printStackTrace();
} finally {
long end = System.currentTimeMillis();
logger.debug("方法" + joinPoint + "耗时 : " + (end - start) + " 毫秒!");
logger.debug("==========结束执行方法环绕通知===============");
}
return retProceed;
}
//拦截无Operatelog的方法
private boolean Intercept(ProceedingJoinPoint joinPoint){
boolean op_type = false;
try {
String targetName = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Class targetClass = Class.forName(targetName);
Method[] methods = targetClass.getMethods();
for (Method method : methods) {
if (method.getName().equals(methodName)) {
op_type = method.getAnnotation(OperateLog.class).op_type();
}
}
} catch (Exception e) {
op_type = false;
}
return op_type;
}
//写入操作日志
private void insertOpLog(ProceedingJoinPoint joinPoint){
//入库
}
//写入错误日志
private void insertOpLogError(ProceedingJoinPoint joinPoint,String str){
//入库
}
}
中间有对自定义注解进行拦截,以便拦截上面哪些方法的操作需要写入数据库操作日志,哪些方法不需要,只需要在log4j中打印
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OperateLog {
/**
* 是否打印到数据库
* true打印到数据库
* false打印到日志文件
* @return
*/
boolean op_type() default true;
}
注意,springboot是1.8以上的jdk,所以其中使用的aspectjweaver.jar包版本也是要对应提高
我这用的是:
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.0</version>
</dependency>
这个jar
代码部分或有缺失,请自行补缺。