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就可以了
相关推荐
本项目“Spring+SpringMvc+MybatisPlus+Aop(自定义注解)动态切换数据源”正是针对这一需求提供的一种解决方案。下面将详细介绍这个项目中的关键技术点和实现原理。 首先,Spring框架是Java企业级应用开发的核心...
4、想看spring aop 注解实现记录系统日志并入库等 二、能学到什么 1、收获可用源码 2、能够清楚的知道如何用spring aop实现自定义注解以及注解的逻辑实现 (需要知道原理的请看spring aop源码,此处不做赘述) 3、...
总结,Spring MVC结合AOP和自定义注解可以方便地实现日志记录功能,无需侵入业务代码。这种方法具有良好的可扩展性和灵活性,可以轻松适应不同场景的日志需求。同时,通过调整切面的定义,我们可以控制日志记录的...
SpringBoot AOP,即面向切面编程,是Spring框架中的一个重要特性,用于实现代码的横切关注点,如日志记录、事务管理、权限验证等。AOP通过使用代理模式,将这些关注点与核心业务逻辑分离,使得代码更加模块化,更...
通过这种方式,我们可以在AOP中灵活地处理带有自定义注解的方法,实现如日志记录、性能监控、权限验证等多种功能。这不仅提高了代码的复用性,也使得业务逻辑更加清晰。 总结来说,Spring中的自定义注解和AOP的结合...
本文我们通过Spring AOP和Java的自定义注解来实现日志的插入功能,该方案对原有业务入侵较低,实现较灵活。下面我们将详细介绍该功能的实现原理和相关知识点。 1. 概述 在一般系统中,当我们做了一些重要的操作时...
在这个“自定义注解实现伪动态传参的小demo”中,我们将探讨如何创建一个自定义注解,以允许在注解中传递类似于动态参数的数据。 首先,自定义注解的定义通常以`@interface`关键字开始,我们可以定义一些元素(也...
总的来说,Spring自定义注解的解析是一个强大且灵活的工具,可以帮助我们实现更精细化的代码组织和控制。结合`@ComponentScan`,我们可以轻松地在Spring环境中管理和利用自定义注解,进一步提升代码的可读性和可维护...
Spring AOP 自定义注解的实现代码 Spring AOP(Aspect-Oriented Programming)是一种面向方面编程的技术,它可以将散布在应用程序中的各种关注点(例如安全、日志、事务等)提取出来,形成一个独立的模块,以便于...
在本文中,我们将探讨如何使用 Spring AOP 实现日志管理,并使用自定义注解方式来记录日志信息。这种方式可以灵活地实现日志管理,提高系统的可维护性和可扩展性。 首先,我们需要在 applicationContext-mvc.xml ...
自定义注解+Spring AOP实现记录用户操作日志-附件资源
总结来说,Spring自定义注解和AOP的结合使用,让我们能够灵活地在代码中插入跨切面的关注点,如日志记录、事务管理、性能监控等,而不必在每个方法中手动添加这些代码。这不仅提高了代码的整洁度,也使得系统更加...
同时,Spring的AOP机制允许我们定义横切关注点,如日志记录、事务管理等,使得代码更加模块化和易于维护。 Hibernate是Java领域中流行的ORM(对象关系映射)工具,它消除了直接操作数据库的需要。使用Hibernate,...
通过这种方式,我们可以在Spring MVC中利用AOP实现对Controller方法的透明日志管理,不仅记录正常流程,也能捕获和记录异常,提升系统的可维护性和问题排查效率。 在实际项目中,我们可以根据需求进一步定制日志...
同时,我们可以使用拦截器(Interceptor)来添加自定义的行为,如日志记录、权限检查等。 总的来说,本教程涵盖了Spring MVC、Spring和Hibernate的全注解集成,旨在帮助开发者理解如何在实际项目中有效地利用这些...
总结来说,这个示例展示了如何在Spring Boot项目中自定义注解,将其应用于Java Bean的方法,以及如何利用AOP来实现全局扫描和自动执行。这样的实践在系统监控、性能分析和故障排查中非常有用,能够帮助开发者更好地...
在本文中,我们将学习如何在 Spring 项目中使用自定义注解和 Aspect 来实现日志记录功能。我们将从头开始,创建一个简单的 Spring Boot 项目,然后使用自定义注解和 Aspect 来实现日志记录。 自定义注解 首先,...
spring boot 使用AOP+自定义注解+反射实现操作日志记录修改前数据和修改后对比数据,并保存至日志表
总之,Spring AOP提供了一种优雅的方式来实现记录操作日志的需求,通过自定义Aspect和注解,我们可以灵活地控制哪些方法需要记录日志,以及记录什么样的日志信息。这个过程既提高了代码的可维护性,也使得日志管理...