主页:写程序的小王叔叔的博客欢迎来访
支持:点赞
收藏
关注
一、实现效果
二、流程图
三、代码
1.基本注解类 -- 这个要在控制层中引用,后面说引用方式
/***
* 系统日志管理表
* @ClassName: SysLogController
* @Description: TODO(描述)
* @author author
* @date 2019-12-03 10:54:52
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLogAspectValue {
String describtion() default "";//日志描述
String logType() default "1";//日志种类-1:系统日志2:业务日志
String type() default "GET";//请求方式:(GET/POST)
String url() default "";//请求链接
String table() default "";//操作的数据库表
String params() default "";//请求参数
String method() default "";//请求方法
}
2.日志切面方法
/***
* 系统日志切面
* @ClassName: SysLogAspect
* @Description: TODO(描述)
* @author author
* @date 2019-12-04 10:34:41
*/
@Aspect // 使用@Aspect注解声明一个切面
@Component
public class SystemLogAspect{
private final String POINT_CUT ="@annotation(com.*.*.modules.sys.log.entity)";
@Autowired
public SysLogService sysLogService;
/**
* 这里我们使用注解的形式
* 当然,我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method
* 切点表达式: execution(...)
*/
@Pointcut(POINT_CUT)
public void PointCut() {}
/**
* 环绕通知 @Around , 当然也可以使用 @Before (前置通知) @After (后置通知)
* @param point
* @return
* @throws Throwable
*/
//@Around(POINT_CUT)
@Around("@annotation(SysLogAspectValue)")
public Object around(ProceedingJoinPoint point) throws Throwable {
long beginTime = System.currentTimeMillis();
Object result = point.proceed();
try {
//正常保存日志
saveLog(point, System.currentTimeMillis() - beginTime);
} catch (Exception e) {
//异常保存日志
//afterReturningMethod(point, e);
}
return result;
}
/***
* 捕获异常
*
* @Title: afterReturningMethod
* @Description: TODO(描述)
* @param joinPoint
* @param e
* @author author
* @throws Throwable
* @date 2019-12-10 01:40:37
*/
@AfterThrowing(throwing = "exception",value = "@annotation(SysLogAspectValue)",argNames="exception")
public void afterReturningMethod(JoinPoint joinPoint, Exception e) throws Throwable{
if(e!=null){
SysLog sysLog = new SysLog();
long beginTime = System.currentTimeMillis();
long time = System.currentTimeMillis() - beginTime;
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
sysLog.setId(IdGenerate.longUUIDId());//主键
sysLog.setLogId(sysLog.getId().toString());//日志编号
sysLog.setTime(time);//时长
sysLog.setIp(request.getRemoteAddr());//请求的IP
sysLog.setCreateBy(sysLog.getIp());//请求人
sysLog.setCreateTime( new Date() );//创建时间
SysLogAspectValue sysLogAspectValue = method.getAnnotation(SysLogAspectValue.class);
if(sysLogAspectValue != null){
//注解上的描述
sysLog.setLogComment(sysLogAspectValue.describtion());//备注
sysLog.setLogType(sysLogAspectValue.logType());//日志类型
sysLog.setType(sysLogAspectValue.type());//请求类型
sysLog.setUrl(sysLogAspectValue.url());//请求链接
sysLog.setTable(sysLogAspectValue.table());//操作的数据表
sysLog.setMethod(sysLogAspectValue.method());//操作请求方法
}
//请求的 类名、方法名
sysLog.setClassName(joinPoint.getTarget().getClass().getName());//类名
sysLog.setMethodName(signature.getName());//方法名
//请求的参数
Object[] args = joinPoint.getArgs();
List<String> list = new ArrayList<String>();
for (Object o : args) {
list.add(new Gson().toJson(o));
}
sysLog.setParams("Params:[ " + list.toString()+" ]:Aspectj @AfterThrowing");
sysLog.setLogError(joinPoint.getSignature().getName()+ "[ message:" + e.getMessage() + "]:Aspectj @AfterThrowing");
System.out.println("=====异常保存日志成功==============================");
sysLogService.save(sysLog);
System.out.println("=====异常保存日志 结束=========================");
}
}
/**
* 正常保存日志
* @param joinPoint
* @param time
* @throws Throwable
*/
public void saveLog(ProceedingJoinPoint joinPoint, long time) {
SysLog sysLog = new SysLog();
sysLog = this.addSysLog(joinPoint,sysLog , time );
//请求的参数
Object[] args = joinPoint.getArgs();
List<String> list = new ArrayList<String>();
for (Object o : args) {
list.add(new Gson().toJson(o));
}
sysLog.setParams("Params:[ " + list.toString()+" ]:Aspectj @Around");
sysLog.setLogError( "[ message: 无 ]:Aspectj @Around");
System.out.println("=====正常保存日志成功==============================");
sysLogService.save(sysLog);
System.out.println("=====正常保存日志 结束=========================");
}
/**
* 组装日志model
* @Title: addSysLog
* @Description: TODO(描述)
* @param sysLog
* @return
* @author author
* @date 2019-12-10 02:09:04
*/
public SysLog addSysLog(ProceedingJoinPoint joinPoint, SysLog sysLog , long time) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
// 接收到请求,记录请求内容
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
sysLog.setId(IdGenerate.longUUIDId());//主键
sysLog.setLogId(sysLog.getId().toString());//日志编号
sysLog.setTime(time);//时长
sysLog.setIp(request.getRemoteAddr());//请求的IP
sysLog.setCreateBy(sysLog.getIp());//请求人
sysLog.setCreateTime( new Date() );//创建时间
SysLogAspectValue sysLogAspectValue = method.getAnnotation(SysLogAspectValue.class);
if(sysLogAspectValue != null){
//注解上的描述
sysLog.setLogComment(sysLogAspectValue.describtion());//备注
sysLog.setLogType(sysLogAspectValue.logType());//日志类型
sysLog.setType(sysLogAspectValue.type());//请求类型
sysLog.setUrl(sysLogAspectValue.url());//请求链接
sysLog.setTable(sysLogAspectValue.table());//操作的数据表
sysLog.setMethod(sysLogAspectValue.method());//操作请求方法
}
//请求的 类名、方法名
sysLog.setClassName(joinPoint.getTarget().getClass().getName());//类名
sysLog.setMethodName(signature.getName());//方法名
return sysLog;
}
}
3.引用方法
/***
* 菜单管理信息
* @ClassName: SysMenuController
* @Description: TODO(描述)
* @author author
* @date 2019-12-04 02:29:39
*/
@CrossOrigin
@RestController
@RequestMapping("/SysMenu")
public class SysMenuController {
@Autowired
public SysMenuService sysMenuService;
//-------------引用方法-------------------------------添加AOP注解日志管理
@SysLogAspectValue(
describtion = "添加一个新的菜单",
logType = "1",
type="POST",
url="/SysMenu/SaveOneSysMenu",
table="sys_menu",
params = "SysMenu"
)
//-------------------------------------------------------------------
@ResponseBody
@ApiOperation(value = "添加一个新的菜单", notes = "/SysMenu/SaveOneSysMenu")
@PostMapping(value = "/SaveOneSysMenu")
public SysMenu SaveOneSysMenu(@RequestBody SysMenu sysMenu){
return sysMenuService.saveOneSysMenu(sysMenu);
}
//添加AOP注解日志管理
@SysLogAspectValue(
describtion = "查询菜单信息",
logType = "1",
type="POST",
url="/SysMenu/SelectAllSysMenu",
table="sys_menu",
params = "SysMenu"
)
@ResponseBody
@ApiOperation(value = "查询菜单信息", notes = "/SysMenu/SelectAllSysMenu")
@GetMapping(value = "/SelectAllSysMenu")
public List<SysMenu> SelectAllSysMenu(){
return sysMenuService.SelectAllSysMenu();
}
//添加AOP注解日志管理
@SysLogAspectValue(
describtion = "修改菜单信息",
logType = "1",
type="POST",
url="/SysMenu/ModifySysMenu",
table="sys_menu",
params = "SysMenu"
)
@ResponseBody
@ApiOperation(value = "修改菜单信息", notes = "/SysMenu/ModifySysMenu")
@PostMapping(value = "/ModifySysMenu")
public List<SysMenu> ModifySysMenu(@RequestBody SysMenu sysMenu){
sysMenuService.ModifySysMenu(sysMenu);
return this.sysMenuService.SelectAllSysMenu();
}
//添加AOP注解日志管理
@SysLogAspectValue(
describtion = "删除一个菜单信息",
logType = "1",
type="POST",
url="/SysMenu/DelOneSysMenu",
table="sys_menu",
params = "mapId"
)
@ResponseBody
@ApiOperation(value = "删除一个菜单信息", notes = "/SysMenu/DelOneSysMenu")
@PostMapping(value = "/DelOneSysMenu")
public List<SysMenu> DelOneSysMenu(@RequestBody Map<Object,Object> mapId){
sysMenuService.DelOneSysMenu(mapId.get("menuId").toString());
return this.sysMenuService.SelectAllSysMenu();
}
}
4.日志实体类
@Entity
@Table(name = "sys_log")
@Component
@org.hibernate.annotations.Table(comment="系统日志信息", appliesTo = "sys_log")
public class SysLog implements Serializable{
private static final long serialVersionUID = 42L;
@Id
@ApiModelProperty("主键")
@Column(name="id",nullable = false,columnDefinition = "bigint(64) comment '主键'")
private Long id;// 主键Id
@ApiModelProperty("日志编号")
@Column(name="log_id",columnDefinition = "varchar(255) comment '日志编号'" )
private String logId;//日志编号
@ApiModelProperty("请求链接")
@Column(name="url",columnDefinition = "text comment '请求链接'" )
private String url;//请求链接
@ApiModelProperty("请求方法")
@Column(name="method",columnDefinition = "text comment '请求方法'" )
private String method;//请求方法
@ApiModelProperty("请求类名")
@Column(name="class_name",columnDefinition = "text comment '请求类名'" )
private String className;//请求方法
@ApiModelProperty("请求方法名")
@Column(name="method_name",columnDefinition = "text comment '请求方法名'" )
private String methodName;//请求方法
@ApiModelProperty("请求参数")
@Column(name="params",columnDefinition = "text comment '请求参数'" )
private String params;//请求参数
@ApiModelProperty("日志类型:(1:系统日志2:业务日志)")
@Column(name="lot_type",columnDefinition = "varchar(255) comment '日志类型:(1:系统日志2:业务日志)'" )
private String logType;//请求方法
@ApiModelProperty("请求方式:(GET/POST)")
@Column(name="type",columnDefinition = "varchar(255) comment '请求方式(GET/POST)'" )
private String type;//请求方法
@ApiModelProperty("请求IP")
@Column(name="IP",columnDefinition = "text comment '请求IP'" )
private String ip;//请求方法
@ApiModelProperty("操作的数据库表")
@Column(name="log_table",columnDefinition = "varchar(255) comment '操作的数据库表'" )
private String table;//操作的数据库表
@ApiModelProperty("请求异常")
@Column(name="log_error",columnDefinition = "text comment '请求异常'" )
private String logError;//请求异常
@ApiModelProperty("运行时长")
@Column(name="time",columnDefinition = "varchar(255) comment '运行时长'" )
private long time;//
@ApiModelProperty("备注")
@Column(name="log_comment",columnDefinition = "text comment '备注'" )
private String logComment;//备注
@ApiModelProperty("创建人")
@Column(name="create_by" )
private String createBy;//创建人
@ApiModelProperty("创建时间")
@Column(name="create_time" )
private Date createTime;//创建时间
//实现setter/getter
}
以上就是AOP实现切面的日志管理,有问题的欢迎指正,然后我修改,让程序更加完美。
⚠️注意 ~
💯本期内容就结束了,如果内容有误,麻烦大家评论区指出!
如有疑问❓可以在评论区留言💬或私信留言💬,尽我最大能力🏃♀️帮大家解决👨🏫!
如果我的文章有帮助到您,欢迎点赞+关注✔️鼓励博主🏃,您的鼓励是我分享的动力🏃🏃🏃~