Spring AOP实践--记录类方法执行时间
网上有许多关于记录方法执行时间的帖子,但是看了一下,基本上操作不方便,或者都是开发测试性质的不太适用,我在这里做了完善,直接内置到项目中,使用的时候只需要在方法上添加注解@MethodLog即可,非常方法,现记录下来
现在要求如下:
要将service业务层的方法都记录下来方法执行时间,用户进行的操作
所要引入的包括三部分:
1 log日志部分,目前,系统里面的日志用的log4j;
2 方法记录注解;
3 aop切面记录工具类;
4 spring配置文件;
第一 log4j的配置就不需要在此唠叨,如果不清楚可以直接百度,此处只是用一下记录日志
第二 方法记录注解MethodLog,用于在类方法中记录相关操作
package com.june.common.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* 在方法上标记操作备注,及操作类型,用于记录用户操作日志描述
*
* @author 王俊伟 wjw.happy.love@163.com
* @date 2016年12月8日 下午3:38:19
*/
@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MethodLog {
String module() default ""; //功能模块
String remark() default ""; // 操作备注
String operateType() default ""; // 操作类型:Add/Update/Delete/Search/Login等
}
第三 aop切面工具类 LogAspect 该类可以获取切点进行通知,记录MethodLog中的相关信息,已经类方法执行时间
工具类如下
package com.june.common.aspect;
import java.lang.reflect.Method;
import java.net.URLDecoder;
import java.sql.Timestamp;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.lang.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StopWatch;
import com.june.common.Constants;
import com.june.common.annotation.MethodLog;
import com.june.dto.back.common.LogOperateDto;
import com.june.service.back.common.LogOperateService;
/**
* 操作日志记录,添加、删除、修改、查询等方法的AOP
*
* @author 王俊伟 wjw.happy.love@163.com
* @date 2016年12月8日 下午3:44:11
*/
@Aspect
public class LogAspect {
/**
* 日志记录 service
*/
@Autowired
private LogOperateService logService;
@Pointcut("@annotation(com.june.common.annotation.MethodLog)")
public void methodCachePointcut() {
}
@Before("methodCachePointcut()")
public void before(){
}
@After("methodCachePointcut()")
public void after(){
}
/**
* spring aop中@Around @Before @After
* 三个注解的区别
*
* * '@Before是在所拦截方法执行之前执行一段逻辑。
* '@After 是在所拦截方法执行之后执行一段逻辑。
* '@Around是可以同时在所拦截方法的前后执行一段逻辑。
*
* * @param point * @return * @throws Throwable * @date 2016年12月8日 下午4:32:17 * @writer iscas */ @Around("methodCachePointcut()") public Object around(ProceedingJoinPoint point) throws Throwable { Object object; // 获取登录管理员id String adminUserId = logService.getLoginUserId(); if (adminUserId == null) {// 没有管理员登录 return null; } String className = point.getThis().getClass().getName(); // 类名 if (className.indexOf("$$EnhancerByCGLIB$$") > -1) { // 如果是CGLIB动态生成的类 try { className = className.substring(0, className.indexOf("$$")); } catch (Exception ex) { ex.printStackTrace(); } } String methodName = className + "." + point.getSignature().getName(); // 获取方法名 Object[] methodParam = null; // 参数 String params = ""; StopWatch watch = null; try { methodParam = point.getArgs(); // 获取方法参数 // 判断参数类型 if (methodParam[0] instanceof Map) { @SuppressWarnings("unchecked") MapparamsMap = logService.getParameterMap((Map) methodParam[0]); params = logService.mapToString(paramsMap); } else if (methodParam[0] instanceof HttpServletRequest) { HttpServletRequest request = (HttpServletRequest) methodParam[0]; String appParams = request.getParameter("paramsJson"); // app端传来的参数 if (!StringUtils.isBlank(appParams) && !StringUtils.isEmpty(appParams)) { // 如果是APP端操作,修改编码 String udStr = URLDecoder.decode(appParams, "UTF-8"); params = udStr; } else { params = logService.getParams(request); } } //采用StopWatch计算方法执行时间 watch = new StopWatch(); watch.start(); object = point.proceed(); watch.stop(); } catch (Exception e) { throw e; } // @MethodLog(module = "用户管理", remark = "用户信息页面初始化", operateType = // Constants.OPERATE_TYPE_SEARCH) MapmethodMap = getMethodRemark(point); String methodRemark = ""; // 操作备注 String operateType = ""; // 操作类型 String funModule = ""; // 功能模块 if (methodMap != null) { funModule = methodMap.get("module"); methodRemark = methodMap.get("remark"); // 获取操作备注 operateType = methodMap.get("operateType"); // 获取操作类型 //记录耗时 methodRemark +=",执行耗时:"+watch.getTotalTimeMillis()+"ms"; } LogOperateDto logDto = new LogOperateDto(); logDto.setUserId(adminUserId); logDto.setFunModule(funModule); logDto.setOperateType(operateType); logDto.setOperateRemark(methodRemark); // 操作备注 logDto.setOperateMethod(methodName); logDto.setOpetateParams(params); Timestamp now = new Timestamp(System.currentTimeMillis()); logDto.setOperateTime(now); logService.addLogOperate(logDto); // 添加日志记录 return object; } /** * 获取方法的中文备注,用于记录用户的操作日志描述 * * @param joinPoint * @return * @throws Exception * @date 2016年12月8日 下午3:45:23 * @writer iscas */ public static MapgetMethodRemark(JoinPoint joinPoint) throws Exception { MapmethodMap = new HashMap(); ClasstargetClass = joinPoint.getTarget().getClass(); String methodName = joinPoint.getSignature().getName(); Object[] parameterTypes = joinPoint.getArgs(); for (Method method : targetClass.getDeclaredMethods()) { if (method.getName().equals(methodName) && method.getParameterTypes().length == parameterTypes.length) { MethodLog methodLog = method.getAnnotation(MethodLog.class); if (methodLog != null) { methodMap.put("module", methodLog.module()); methodMap.put("remark", methodLog.remark()); methodMap.put("operateType", methodLog.operateType()); return methodMap; } break; } } return null; } }
第四 spring配置文件
<!-- aop -->
<bean id="logAspect" class="com.june.common.aspect.LogAspect"></bean>
业务编程的时候,在每一个业务方法上加入MethodLog注解,例如:获取用户数据操作
@RequestMapping("/getAllList")
@MethodLog(module = "用户管理", remark = "获取所有用户信息", operateType = Constants.OPERATE_TYPE_SEARCH)
public void getAllList(HttpServletRequest request, HttpServletResponse response) {
UserInfoDto userInfoDto = new UserInfoDto();
fillRequestDto(request, userInfoDto);
List<UserInfoDto> list = userInfoService.getDtos(userInfoDto);
toJson(list, response);
}
那么在调用到这个方法的时候,就会在数据库中记录下相关日志
![](/assets/blank.gif)
Spring AOP实践--记录类方法执行时间相关推荐
- spring aop实践_使用Spring AOP实现活动记录模式
spring aop实践 在课堂设计过程中,我们应就每个班级的职责分配做出决定. 如果我们选择的不错,系统将更易于理解,维护和扩展. 我们几乎所有的项目都有一个持久层,即关系数据库,文档存储或仅XML ...
- spring --aop(日志记录)在工程中实际使用
2019独角兽企业重金招聘Python工程师标准>>> ###1.日志切面 package com.readygo.zbhealth.common;import java.util. ...
- Spring AOP 切面记录操作日志
前言 实际业务,有时候需要记录服务的操作日志,我们可以利用SpringAOP 切面来拦截记录用户操作:用户使用session或者前端传值都可以. 1.创建日志记录接口 首先我们得有一个接口,这个接口可 ...
- 从AOP到Spring AOP
文章目录 一.前言 二.AOP基础知识 2.1 AOP 2.1.1 引子:AOP,AOP是什么? 2.1.2 使用对比的方式理解AOP--AOP与OOP 2.1.3 使用对比的方式理解AOP--静态A ...
- Spring AOP实例——异常处理和记录程序执行时间
Spring AOP实例--异常处理和记录程序执行时间 参考文章: (1)Spring AOP实例--异常处理和记录程序执行时间 (2)https://www.cnblogs.com/victoria ...
- spring boot aop 记录方法执行时间
了性能调优,需要先统计出来每个方法的执行时间,直接在方法前后log输出太麻烦,可以用AOP来加入时间统计 添加依赖 <dependency> <groupId>org.spri ...
- 在 Spring Boot 中使用 Spring AOP 和 AspectJ 来测量方法的执行时间
原文链接:https://dzone.com/articles/logging-average-method-execution-times-via-aspectj 作者:Murat Derman 译 ...
- Spring AOP中的静态代理和动态代理的原理和实践
对于最近博主最近写博客的兴致大发,我也在思考:为什么而写博客?在互联网时代,无论你是牛人大咖,还是小白菜鸟,都有发表自己看法的权利.无论你是对的还是错的,都会在这个平台上找到答案.所以,我会尽可能去写 ...
- spring - AOP(6)- 记录后台管理员操作日志
一.需求 1.1 问题 后台一些涉及到新增.编辑.删除等敏感操作的需要记录下操作日志,包含操作人.操作内容.请求参数等等信息. 1.2 思路 统一对Controller层的方法进行拦截,记录下请求信息 ...
最新文章
- router6 QoS 1 基础知识
- Virtual Machine Manager 2008 2008 R2系列之安装部署
- 光流 | MATLAB实现HS Optical Flow(代码类)
- 无监督构建词库:更快更好的新词发现算法
- 双向dcdc变换器simulink仿真_台达_OBC双向充电_HighEfficiency HighDensity GaNBased 6.6kW
- Java--对象内存布局
- java考驾照_基于JavaWeb的驾校考试系统.doc
- gitee提交突然报错remote: Incorrect username or password ( access token )
- 只需五步,快速构建Python聊天室
- 阿里专家:怎么样消除程序员的中年危机?
- Matlab学习(可以用MATLAB作曲)
- 手机java jdk环境配置文件_JDK怎么安装与配置环境变量
- element-ui分页器的使用
- Mac 上使用windows软件--wineskin
- 音视频开发之旅(41)-天空盒
- 报错:undefined symbol: _ZN10tensorflow12OpDefBuilder4AttrESs
- 查看详细Windows VISTA 或Windows 7激活状态
- 奇异网盘点全球10大最荒诞的“时髦”事件
- html中footer怎么写,HTML DOM Footer用法及代码示例
- Adobe XD 下载和安装教程