主页:写程序的小王叔叔的博客欢迎来访👀
支持:点赞收藏关注
1、技术
JDK1.8+
SpringBoot2.0+ 、@Aspect注解
MySql5.6+
2、代码干货
Log实体对象类.java
package*****.***.***.modules.sys.log.entity; importjava.io.Serializable; importjava.util.Date; importjavax.persistence.Column; importjavax.persistence.Entity; importjavax.persistence.Id; importjavax.persistence.Table; importorg.springframework.stereotype.Component; importio.swagger.annotations.ApiModelProperty; name="sys_log") (hibernate.annotations.Table(comment="系统日志信息", appliesTo="sys_log") .publicclassSysLogimplementsSerializable{ privatestaticfinallongserialVersionUID=42L; "主键") (name="id",nullable=false,columnDefinition="bigint(64) comment '主键'") (privateLongid;// 主键Id"日志编号") (name="log_id",columnDefinition="varchar(255) comment '日志编号'" ) (privateStringlogId;//日志编号"请求链接") (name="url",columnDefinition="text comment '请求链接'" ) (privateStringurl;//请求链接"请求方法") (name="method",columnDefinition="text comment '请求方法'" ) (privateStringmethod;//请求方法"请求类名") (name="class_name",columnDefinition="text comment '请求类名'" ) (privateStringclassName;//请求方法"请求方法名") (name="method_name",columnDefinition="text comment '请求方法名'" ) (privateStringmethodName;//请求方法"请求参数") (name="params",columnDefinition="text comment '请求参数'" ) (privateStringparams;//请求参数"日志类型:(1:系统日志2:业务日志)") (name="lot_type",columnDefinition="varchar(255) comment '日志类型:(1:系统日志2:业务日志)'" ) (privateStringlogType;//请求方法"请求方式:(GET/POST)") (name="type",columnDefinition="varchar(255) comment '请求方式(GET/POST)'" ) (privateStringtype;//请求方法"请求IP") (name="IP",columnDefinition="text comment '请求IP'" ) (privateStringip;//请求方法"操作的数据库表") (name="log_table",columnDefinition="varchar(255) comment '操作的数据库表'" ) (privateStringtable;//操作的数据库表"请求异常") (name="log_error",columnDefinition="text comment '请求异常'" ) (privateStringlogError;//请求异常"运行时长") (name="time",columnDefinition="varchar(255) comment '运行时长'" ) (privatelongtime;//"备注") (name="log_comment",columnDefinition="text comment '备注'" ) (privateStringlogComment;//备注"创建人") (name="create_by" ) (privateStringcreateBy;//创建人"创建时间") (name="create_time" ) (privateDatecreateTime;//创建时间//setter()/getter();}
3、基本的CRUD
package****.****.****.modules.sys.log.controller; importjava.util.List; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.web.bind.annotation.CrossOrigin; importorg.springframework.web.bind.annotation.GetMapping; importorg.springframework.web.bind.annotation.RequestMapping; importorg.springframework.web.bind.annotation.ResponseBody; importorg.springframework.web.bind.annotation.RestController; import*****.modules.sys.log.entity.SysLog; import*******.modules.sys.log.service.SysLogService; importio.swagger.annotations.ApiOperation; //跨域"/SysLog") (publicclassSysLogController{ publicSysLogServicesysLogService; // //添加AOP注解日志管理// @SysLogAspectValue(// describtion = "获取所有日志列表信息",// logType = "1",// type="POST",// url="/SysLog/SelectAllSysLog",// table="sys_log",// params = "SysLog",// method = "POST"// )value="获取所有日志列表信息", notes="/SysLog/SelectAllSysLog") (value="/SelectAllSysLog") (publicList<SysLog>SelectAllSysLog(){ returnsysLogService.SelectAllSysLogList(page).getContent(); } }
package*******.*****.******modules.sys.log.service; importorg.springframework.data.domain.Page; import***.***.****t.modules.sys.log.entity.SysLog; /**** 系统日志接口* @ClassName: SysLogService* @Description: TODO(描述)* @author author* @date 2019-12-03 10:55:22*/publicinterfaceSysLogService { /**** 日志保存* @Title: save* @Description: TODO(描述)* @param sysLog* @author author* @date 2019-12-10 09:56:28*/voidsave(SysLogsysLog); }
package***.****.****.modules.sys.log.service.impl; importjava.util.ArrayList; importjava.util.List; importjavax.persistence.criteria.CriteriaBuilder; importjavax.persistence.criteria.CriteriaQuery; importjavax.persistence.criteria.Predicate; importjavax.persistence.criteria.Root; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.data.domain.Page; importorg.springframework.data.domain.PageRequest; importorg.springframework.data.domain.Pageable; importorg.springframework.data.domain.Sort; importorg.springframework.data.jpa.domain.Specification; importorg.springframework.stereotype.Service; import***.***.***.***.****.modules.sys.log.entity.SysLog; import***.*.*.*.*.*.*.*.modules.sys.log.repository.SysLogRepository; import*.*.*.*.*.*.*.*.*.*.modules.sys.log.service.SysLogService; /*** 系统日志实现类* @ClassName: SysLogServiceImpl* @Description: TODO(描述)* @author author* @date 2019-12-03 10:55:17*/"SysLogService") (publicclassSysLogServiceImplimplementsSysLogService{ publicSysLogRepositorysysLogRepository; publicPage<SysLog>SelectAllSysLogList(intpage) { Sortsort=newSort(Sort.Direction.DESC, "createTime");//创建时间正序排列Pageablepageable=PageRequest.of(page, this.size, sort); Page<SysLog>sysLog=sysLogRepository.findAll (newSpecification<SysLog>() { publicPredicatetoPredicate(Root<SysLog>root, CriteriaQuery<?>query, CriteriaBuildercriteriaBuilder) { List<Predicate>list=newArrayList<Predicate>(); //拼接 where条件-----------------//---------------------------Predicate[] p=newPredicate[list.size()]; returncriteriaBuilder.and(list.toArray(p)); } }, pageable); returnsysLog; } publicvoidsave(SysLogsysLog) { sysLogRepository.save(sysLog); } }
package*.*.*.*.*.*.*.modules.sys.log.repository; importorg.springframework.data.jpa.domain.Specification; importorg.springframework.data.jpa.repository.JpaRepository; import*.*.*.*.*.*.*.*.modules.sys.log.entity.SysLog; /*** 系统日志管理类* @ClassName: SysLogRepository* @Description: TODO(描述)* @author author* @date 2019-12-03 10:55:09*/publicinterfaceSysLogRepositoryextendsJpaRepository<SysLog, Long> { }
已上就是基本的业务功能中的CRUD的功能,下面就是重点的log的AOP切面功能,,,
4、AOP切面功能动态获取log信息
1)、在每个需要用到的方法头上增加注释,附加案例【四中第一个截图】
package*.*.*.*.*.*.*.*.modules.sys.log.controller; importjava.lang.annotation.Documented; importjava.lang.annotation.ElementType; importjava.lang.annotation.Retention; importjava.lang.annotation.RetentionPolicy; importjava.lang.annotation.Target; /**** 系统日志管理表* @ClassName: SysLogController* @Description: TODO(描述)* @author author* @date 2019-12-03 10:54:52*/ElementType.METHOD) (RetentionPolicy.RUNTIME) (//注释文档public@interfaceSysLogAspectValue { Stringdescribtion() default"";//日志描述StringlogType() default"1";//日志种类-1:系统日志2:业务日志Stringtype() default"GET";//请求方式:(GET/POST)Stringurl() default"";//请求链接Stringtable() default"";//操作的数据库表Stringparams() default"";//请求参数Stringmethod() default"";//请求方法}
制作切面内容
package*.*.*.*.*.*.*.modules.sys.log.controller; importjava.lang.reflect.Method; importjava.util.ArrayList; importjava.util.Date; importjava.util.List; importjavax.servlet.http.HttpServletRequest; importorg.aspectj.lang.JoinPoint; importorg.aspectj.lang.ProceedingJoinPoint; importorg.aspectj.lang.annotation.AfterThrowing; importorg.aspectj.lang.annotation.Around; importorg.aspectj.lang.annotation.Aspect; importorg.aspectj.lang.annotation.Pointcut; importorg.aspectj.lang.reflect.MethodSignature; importorg.springframework.beans.factory.annotation.Autowired; importorg.springframework.stereotype.Component; importorg.springframework.web.context.request.RequestContextHolder; importorg.springframework.web.context.request.ServletRequestAttributes; importcom.google.gson.Gson; import*.*.*.*.*.*.common.utils.IdGenerate; import*.*.*.*.*.*.modules.sys.log.entity.SysLog; import*.*.*.*.*.*.modules.sys.log.service.SysLogService; /**** 系统日志切面* @ClassName: SysLogAspect* @Description: TODO(描述)* @author author* @date 2019-12-04 10:34:41*/// 使用@Aspect注解声明一个切面publicclassSystemLogAspect{ privatefinalStringPOINT_CUT="@annotation(*.*.*.*.*.modules.sys.log.entity)"; privatestaticfinalorg.slf4j.Loggerlog=org.slf4j.LoggerFactory.getLogger(SystemLogAspect.class); publicSysLogServicesysLogService; /*** 这里我们使用注解的形式* 当然,我们也可以通过切点表达式直接指定需要拦截的package,需要拦截的class 以及 method* 切点表达式: execution(...)*/POINT_CUT) (publicvoidPointCut() {} /*** 环绕通知 @Around , 当然也可以使用 @Before (前置通知) @After (后置通知)* @param point* @return* @throws Throwable*///@Around(POINT_CUT)"@annotation(SysLogAspectValue)") (publicObjectaround(ProceedingJoinPointpoint) throwsThrowable { longbeginTime=System.currentTimeMillis(); Objectresult=point.proceed(); try { //正常保存日志saveLog(point, System.currentTimeMillis() -beginTime); } catch (Exceptione) { //异常保存日志//afterReturningMethod(point, e); } returnresult; } /**** 捕获异常* * @Title: afterReturningMethod* @Description: TODO(描述)* @param joinPoint* @param e* @author author* @throws Throwable * @date 2019-12-10 01:40:37*/throwing="exception",value="@annotation(SysLogAspectValue)",argNames="exception") (publicvoidafterReturningMethod(JoinPointjoinPoint, Exceptione) throwsThrowable{ if(e!=null){ SysLogsysLog=newSysLog(); longbeginTime=System.currentTimeMillis(); longtime=System.currentTimeMillis() -beginTime; MethodSignaturesignature= (MethodSignature) joinPoint.getSignature(); Methodmethod=signature.getMethod(); // 接收到请求,记录请求内容ServletRequestAttributesattributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequestrequest=attributes.getRequest(); sysLog.setId(IdGenerate.longUUIDId());//主键sysLog.setLogId(sysLog.getId().toString());//日志编号sysLog.setTime(time);//时长sysLog.setIp(request.getRemoteAddr());//请求的IPsysLog.setCreateBy(sysLog.getIp());//请求人sysLog.setCreateTime( newDate() );//创建时间SysLogAspectValuesysLogAspectValue=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=newArrayList<String>(); for (Objecto : args) { list.add(newGson().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); log.trace(POINT_CUT, sysLog); System.out.println("=====异常保存日志 结束========================="); } } /*** 正常保存日志* @param joinPoint* @param time* @throws Throwable */publicvoidsaveLog(ProceedingJoinPointjoinPoint, longtime) { SysLogsysLog=newSysLog(); sysLog=this.addSysLog(joinPoint,sysLog , time ); //请求的参数Object[] args=joinPoint.getArgs(); List<String>list=newArrayList<String>(); for (Objecto : args) { list.add(newGson().toJson(o)); } sysLog.setParams("Params:[ "+list.toString()+" ]:Aspectj @Around"); sysLog.setLogError( "[ message: 无 ]:Aspectj @Around"); System.out.println("=====正常保存日志成功=============================="); sysLogService.save(sysLog); log.trace(POINT_CUT, sysLog); System.out.println("=====正常保存日志 结束========================="); } /*** 组装日志model* @Title: addSysLog* @Description: TODO(描述)* @param sysLog* @return* @author author* @date 2019-12-10 02:09:04*/publicSysLogaddSysLog(ProceedingJoinPointjoinPoint, SysLogsysLog , longtime) { MethodSignaturesignature= (MethodSignature) joinPoint.getSignature(); Methodmethod=signature.getMethod(); // 接收到请求,记录请求内容ServletRequestAttributesattributes= (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequestrequest=attributes.getRequest(); sysLog.setId(IdGenerate.longUUIDId());//主键sysLog.setLogId(sysLog.getId().toString());//日志编号sysLog.setTime(time);//时长sysLog.setIp(request.getRemoteAddr());//请求的IPsysLog.setCreateBy(sysLog.getIp());//请求人sysLog.setCreateTime( newDate() );//创建时间SysLogAspectValuesysLogAspectValue=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());//方法名returnsysLog; } }
生成这个Log切面日志的用法:
转载声明:本文为博主原创文章,未经博主允许不得转载
⚠️注意 ~
💯本期内容就结束了,如果内容有误,麻烦大家评论区指出!
如有疑问❓可以在评论区💬或私信💬,尽我最大能力🏃♀️帮大家解决👨🏫!
如果我的文章有帮助到您,欢迎点赞+关注✔️鼓励博主🏃,您的鼓励是我分享的动力🏃🏃🏃~