最近项目中需要记录日志,跟大家想的一样 ,利用spring aop去实现,之前也参考了一些代码,自己实现了一套设计,供大家参考。
之前看到网上很多是基于切面类Aspect去实现了,在切面类中定义before after around等逻辑以及要拦截等方法。本文利用注解实现了一套可以扩展等日志记录模块。
1. 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public abstract @interface RequiredLogInterceptor {
boolean required() default true;
String targetGenerator() default "";
OperateType operateType() default OperateType.GET;
}
requried:注解是否生效
targetGenerator: 每个模块记录等内容不同,入口参数不同,所以需要个性化定制日志等记录内容,每个模块的日志生成有自己定义的generator类,并且重写generateContent方法。
operateType:当前方法是增加,删除,还是修改
public abstract class ContentGerator {
public static String SPLIT="/";
public static String CONTENT_SPLIT=",";
public static String VALUE_SPLIT=":";
abstract List<UserOperateLog> generateContent(Object returnValue, Object[] args, OperateType operateType);
}
2. 定义拦截器
本模块主要是后置通知,主要逻辑如下:
1.拦截方法,判断是否有注解loginterceptor
2. 如果有判断是否执行成功,成功则记录log,失败不记录
3. 获取注解中配置的generator类,利用反射调用generateContent方法,生成个性化日志内容
5.在日志中添加其他公共属性,比如用户id,创建时间等等。所有个性化定制的日志信息都是在generator类中产生。
public class LogAfterInterceptor implements AfterReturningAdvice {
@Autowired
private LogService logService;
@Override
public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
RequiredLogInterceptor requiredLogInterceptor = AnnotationUtils.findAnnotation(method, RequiredLogInterceptor.class);
if (requiredLogInterceptor != null) {
if(returnValue!=null&&returnValue instanceof Response){
Response response=(Response)returnValue;
String code=response.getCode();
String code200= MegCodeEnums.ResponseCodeEnum.C200.getCode();
String code201= MegCodeEnums.ResponseCodeEnum.C201.getCode();
if (!Strings.isNullOrEmpty(code)&&!code.equalsIgnoreCase(code200)&&!code.equalsIgnoreCase(code201)){
return;
}
}
String targetGeneratorName=requiredLogInterceptor.targetGenerator();
OperateType operateType=requiredLogInterceptor.operateType();
Class targetGeneratorclass=Class.forName("com.puhui.flowplatform.manage.log."+targetGeneratorName);
Method executeMethod=targetGeneratorclass.getMethod("generateContent",Object.class,Object[].class,OperateType.class);
ContentGerator targetGeneratorBean=(ContentGerator)SpringContextHolder.getBean(targetGeneratorclass);
List<UserOperateLog> userOperateLogList=(List