1,spring配置文件
<bean class="com.able.aop.LogAspect" id="logAspect"/> <aop:config> <aop:aspect id="serviceMonitor" ref="logAspect"> <aop:pointcut expression="execution(* com.able.controller.*.*(..))" id="servicePointcut" /> <aop:around method="doAroundMethodLog" pointcut-ref="servicePointcut"/> </aop:aspect> </aop:config>
2,日志拦截类
public class LogAspect { private static final Logger logger = LoggerFactory.getLogger(LogAspect.class); @Autowired private HttpServletRequest request; @Autowired private UserOperatLogService userOperatLogService; @Autowired private TokenService tokenService; /** * 标注该方法体为环绕通知,当目标方法执行时执行该方法体 */ public Object doAroundMethodLog(ProceedingJoinPoint jp) throws Throwable{ StopWatch stopWatch = new StopWatch(); //记录方法执行耗时 stopWatch.start(); Object retVal = null; try{ retVal = jp.proceed(); }catch (Throwable e){ e.printStackTrace(); logger.error(e.getMessage()); retVal = new ResponseEntity(new RestResult(e.getMessage(),false), HttpStatus.OK); }finally { stopWatch.stop(); insertOpertLog(jp, stopWatch); } return retVal; } private void insertOpertLog(ProceedingJoinPoint jp, StopWatch stopWatch) { Class<? extends Object> classD=jp.getTarget().getClass(); String className = classD.getName(); MethodSignature joinPointObject = (MethodSignature) jp.getSignature(); Method method = joinPointObject.getMethod(); String methodName = method.getName(); if(!jp.getTarget().getClass().isAnnotationPresent(NoLog.class)&&!method.isAnnotationPresent(NoLog.class)){ String params = parseParames(jp.getArgs()); //解析目标方法体的参数 UserOperatLog userOperatLog=new UserOperatLog(); userOperatLog.setIpAddr(request.getRemoteAddr()); userOperatLog.setActionUrl(request.getRequestURI()); userOperatLog.setTimeLong(stopWatch.getTotalTimeMillis()+""); ShiroUser shiroUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal(); if(shiroUser!=null){ userOperatLog.setUserId(shiroUser.getZhsId()); userOperatLog.setUserName(shiroUser.getRealName()); }else{ String tokenCode=request.getParameter("tokenCode")==null?"":request.getParameter("tokenCode"); if(tokenCode!=null && !"".equals(tokenCode)){ Token token = new Token(); token.setTokenCode(tokenCode); List<Token> list =tokenService.selectBySelective(token); if(list != null && list.size() > 0){ token=list.get(0); userOperatLog.setUserId(token.getUserId()); userOperatLog.setUserName(token.getRealName()); } } } Function fd = null; Operate md = null; if(classD.isAnnotationPresent(Function.class)){ fd = classD.getAnnotation(Function.class); } if(method.isAnnotationPresent(Operate.class)){ md =method.getAnnotation(Operate.class); } if(fd!=null){ userOperatLog.setMean(fd.value()); userOperatLog.setModule(fd.moduleName()); userOperatLog.setSubModule(fd.subModuleName()); } if(md!=null){ userOperatLog.setFunction(md.value()); } userOperatLog.setParamData(params); userOperatLog.setCreateTime(DateUtil.getTimeStamp()); logger.info("业务处理"+",模块:["+(fd!=null?fd.moduleName():"")+"],操作:["+(md!=null?md.value():"")+"],调用类名称:["+className+"],调用方法名称:["+methodName+"],参数为:" + params + ";耗时" + stopWatch.getTotalTimeMillis() + "毫秒"); userOperatLogService.insertBySelective(userOperatLog); //userOperatLogService.testasy(); logger.info("执行完毕======="); } }
3,自定义注解三个
功能模块注解
/** * 每个类的功能描述 * @author zhangqh * @date 2016-8-2 下午01:03:59 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented public @interface Function { String value() default ""; String moduleName() default ""; String subModuleName() default ""; }
操作方法注解
/** * 方法描述 * @author zhangqh * @date 2016-8-2 下午12:55:25 */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Operate { String value() default ""; }
不需要记录日志的注解
/** * 免记录日志注解标识 * @author wjhu * @date 2016-8-2 下午01:03:59 */ @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.METHOD, ElementType.TYPE}) @Documented public @interface NoLog { }
4,controller中记录操作日志的使用
/** * @Function注解为对应的操作日志模块 * @author zhangqh * */ @Controller @RequestMapping("/test") @Function(value ="测试模块",moduleName = "测试模块",subModuleName = "") public class test { /** * 会记录对应的操作说明 */ @Operate(value="操作") public void aa(){ } /** * 使用@NoLog注解就不是记录该方法的操作日志了 */ @NoLog public void bb(){ } }
提示:如果记录日志要持久化到数据库的话,建议入库操作加上异步操作这样对性能会提升不少
spring对异步调用方法支持也比较好 配置也比较简单,只需要要在配置文件中加入
<!-- 支持异步加载 --> <task:annotation-driven/>
就可以了,然后使用的方法上加上@Async就可以了
相关推荐
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
SpringMVC利用AOP实现自定义注解记录日志
Spring MVC AOP通过自定义注解方式拦截Controller等实现日志管理, springMVC里做添加AOP拦截,用于捕获异常。
下面小编就为大家分享一篇spring AOP自定义注解方式实现日志管理的实例讲解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
本文我们通过Spring AOP和Java的自定义注解来实现日志的插入功能,非常不错,具有一定的参考借鉴价值,需要的朋友一起看看吧
自定义注解+Spring AOP实现记录用户操作日志-附件资源
springboot 脱敏自定义注解 SpringAOP
+ AOP注解两种模式切面练习 + 项目启动预处理 + 自定义编辑事务架构 + 上传下载 + 传参注解式校验 + session练习 + 公用日志设计封装 + db乐观锁设计 + 优雅启停 + 配置文件信息加密 + AES加解密 + spring 事件监听...
NULL 博文链接:https://conkeyn.iteye.com/blog/2354644
下面小编就为大家分享一篇aop注解方式实现全局日志管理方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
今天主要说说如何通过自定义注解的方式,在 Spring Boot 中来实现 AOP 切面统一打印出入参日志。小伙伴们可以收藏一波。 废话不多说,进入正题 ! 目录 一、先看看切面日志输出效果 二、添加 AOP Maven
时间过的真快,转眼就一年了,没想到随手写的笔记会被这么多人浏览,不想误人子弟,于是整理了一个优化版。感谢各位同道的支持!
日志表:使用aop拦截实现 权限控制:基于token方式,禁用session 对各种不同异常进行了全局统一处理 使用lombok简化java代码,让源码更简洁,可读性高 mybatis未进行二次封装,原滋原味,简单sql采用注解,复杂...
利用自定义注解和spring aop和java反射机制生成用户能够读懂的日志记录。如:用户张三在2013年9月27日17:00执行了用户管理模块的用户删除功能参数为(编号:123456)各位可根据需要写入数据库或者保存到文件。
springboot+自定义注解,实现aop环绕通知自动保存日志的demo
采用 AOP + 自定义注解 + Redis 实现限制IP接口访问次数 采用 Nacos 作为服务发现和配置中心,轻松完成项目的配置的维护 采用 Sentinel 流量控制框架,通过配置再也不怕网站被爆破 支持Markdown 编辑器 采用 Elastic...
自定义注解实现aop日志 自定义注解实现实体类参数校验 添加mybatis自定生成映射实体类、mapper等 添加全局异常处理 添加fegin自定义数据解析 20180907 添加注解,作为参数校验入口 20180910 解决服务之间调用fegin+...
面向AOP编程:通过自定义注解实现接口限流、操作日志记录等 …… 开发环境 工具:IntelliJ IDEA JDK 1.8 数据库:MySQL 8.0.15 项目构建:后端Maven、前端 Webpack 后端 Web框架:Spring Boot 安全框架:Spring ...
Spring.NET是一个应用程序框架,其目的是协助开发人员创建企业级的.NET应用程序。它提供了很多方面的功能,比如依赖注入、面向方面编程(AOP)、数据访问抽象及ASP.NET扩展等等。Spring.NET以Java版的Spring框架为...