自定义一个注解:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Log {
String remark() default "";
}
定义切面类:
@Component
@Aspect
public class LogsAspect {
//获取日志对象
private Logger logger = LoggerFactory.getLogger(LogsAspect.class);
private static String[] types = {"java.lang.Integer", "java.lang.Double",
"java.lang.Float", "java.lang.Long", "java.lang.Short",
"java.lang.Byte", "java.lang.Boolean", "java.lang.Char",
"java.lang.String", "int", "double", "long", "short", "byte",
"boolean", "char", "float"};
//上次mq接口,(个人业务需求)
// @Autowired
// private BehaviorLogService behaviorLogService;
/**
* 切点表达式,统一拦截BehaviorLog注解
* @MethodName: logPointcut
*
* @return: void
* @Author:
* @CreateDate: 2020/2/20 11:48
* @throws
**/
@Pointcut("@annotation(com.icss.model.Log)")
public void logPointcut(){
}
/**
* 后置通知拦截方法,上传打点日志
* @MethodName: logAfter
* @param joinPoint
* @return: void
* @Author:
* @CreateDate: 2020/2/20 12:10
* @throws
**/
@After("logPointcut()")
public void logAfter(JoinPoint joinPoint) throws Exception{
//获取request对象,可以拿到请求ip,Cookies,url等数据,看自己业务需求
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
//获取请求头工号
String lobNumber =request.getHeader("LOBNUMBER");
//获取接口上的注解
Log logs = this.getAnnotation(joinPoint);
String str= logs.remark();
//获取方法参数封装为map
Map map = this.getMethodParameter(joinPoint);
logger.info("==========切面日志打点开始=============");
logger.info("className:"+joinPoint.getTarget().getClass().getSimpleName());
logger.info("methodName:"+joinPoint.getSignature().getName());
logger.info("lobNumber:"+lobNumber);
logger.info("Log:"+str);
if(!StringUtils.isEmpty(lobNumber)&&!StringUtils.isEmpty(str)){
// 上传mq,(个人业务需求)
behaviorLogService.uploadBehaviorLog(String.valueOf(behaviorEnum.getCode()),lobNumber,map);
logger.info("==========切面日志打点上传成功=============");
}
logger.info("==========切面日志打点结束=============");
}
/**
* 获取方法上的日志打点注解
* @MethodName: getAnnotation
* @param joinPoint
* @return: com.icss.scubeboot.annotations.BehaviorLog
* @Author:
* @CreateDate: 2020/2/20 12:05
* @throws
**/
public Log getAnnotation(JoinPoint joinPoint){
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature)signature;
Log logs = methodSignature.getMethod().getAnnotation(Log.class);
return logs;
}
/***
* 获取方法参数,封装为Map
* @MethodName: getMethodParameter
* @param
* @return: java.util.Map
* @Author:
* @CreateDate: 2020/2/20 15:34
* @throws
**/
public Map getMethodParameter(JoinPoint joinPoint){
Map maps = new HashMap<String,Object>(16);
Object[] objs =joinPoint.getArgs();
String[] paramNames = ((CodeSignature) joinPoint.getSignature()).getParameterNames();
for(int i=0;i<objs.length;i++){
Object obj =objs[i];
String typeName = obj.getClass().getTypeName();
for(int k=0;k<types.length;k++){
if(typeName.equals(types[k])){
maps.put(paramNames[i],obj);
continue;
}
}
if(obj instanceof MultipartFile ||obj instanceof ServletRequest ||obj instanceof ServletResponse){
continue;
}
maps = this.getFieldsValue(obj,maps);
}
return maps;
}
/**
* 获取封装类的属性值
* @MethodName: getFieldsValue
* @param obj
* @param map
* @return: java.util.Map
* @Author:
* @CreateDate: 2020/2/20 18:25
* @throws
**/
public Map getFieldsValue(Object obj,Map map) {
Field[] fields = obj.getClass().getDeclaredFields();
String typeName = obj.getClass().getTypeName();
for (Field f : fields) {
//在反射时能访问私有变量
f.setAccessible(true);
try {
if(f.getName().equals("serialVersionUID")){
continue;
}
//for (String str : types) {
//这边会有问题,如果实体类里面继续包含实体类,这边就没法获取。
//其实,我们可以通递归的方式去处理实体类包含实体类的问题。
// if (f.getType().getName().equals(str)) {
map.put(f.getName(),f.get(obj));
//}
// }
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return map;
}
}
在要生成日志的地方加上注解就可以生成日志了:
@Log(remark = “保存用户数据”)
@RequestMapping("/save")
public void saveUser(@RequestBody User user) {
userServiceImpl.saveUser(user);
}