网上有许多关于记录方法执行时间的帖子,但是看了一下,基本上操作不方便,或者都是开发测试性质的不太适用,我在这里做了完善,直接内置到项目中,使用的时候只需要在方法上添加注解@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);
}
那么在调用到这个方法的时候,就会在数据库中记录下相关日志




Spring AOP实践--记录类方法执行时间相关推荐

  1. spring aop实践_使用Spring AOP实现活动记录模式

    spring aop实践 在课堂设计过程中,我们应就每个班级的职责分配做出决定. 如果我们选择的不错,系统将更易于理解,维护和扩展. 我们几乎所有的项目都有一个持久层,即关系数据库,文档存储或仅XML ...

  2. spring --aop(日志记录)在工程中实际使用

    2019独角兽企业重金招聘Python工程师标准>>> ###1.日志切面 package com.readygo.zbhealth.common;import java.util. ...

  3. Spring AOP 切面记录操作日志

    前言 实际业务,有时候需要记录服务的操作日志,我们可以利用SpringAOP 切面来拦截记录用户操作:用户使用session或者前端传值都可以. 1.创建日志记录接口 首先我们得有一个接口,这个接口可 ...

  4. 从AOP到Spring AOP

    文章目录 一.前言 二.AOP基础知识 2.1 AOP 2.1.1 引子:AOP,AOP是什么? 2.1.2 使用对比的方式理解AOP--AOP与OOP 2.1.3 使用对比的方式理解AOP--静态A ...

  5. Spring AOP实例——异常处理和记录程序执行时间

    Spring AOP实例--异常处理和记录程序执行时间 参考文章: (1)Spring AOP实例--异常处理和记录程序执行时间 (2)https://www.cnblogs.com/victoria ...

  6. spring boot aop 记录方法执行时间

    了性能调优,需要先统计出来每个方法的执行时间,直接在方法前后log输出太麻烦,可以用AOP来加入时间统计 添加依赖 <dependency> <groupId>org.spri ...

  7. 在 Spring Boot 中使用 Spring AOP 和 AspectJ 来测量方法的执行时间

    原文链接:https://dzone.com/articles/logging-average-method-execution-times-via-aspectj 作者:Murat Derman 译 ...

  8. Spring AOP中的静态代理和动态代理的原理和实践

    对于最近博主最近写博客的兴致大发,我也在思考:为什么而写博客?在互联网时代,无论你是牛人大咖,还是小白菜鸟,都有发表自己看法的权利.无论你是对的还是错的,都会在这个平台上找到答案.所以,我会尽可能去写 ...

  9. spring - AOP(6)- 记录后台管理员操作日志

    一.需求 1.1 问题 后台一些涉及到新增.编辑.删除等敏感操作的需要记录下操作日志,包含操作人.操作内容.请求参数等等信息. 1.2 思路 统一对Controller层的方法进行拦截,记录下请求信息 ...

最新文章

  1. router6 QoS 1 基础知识
  2. Virtual Machine Manager 2008 2008 R2系列之安装部署
  3. 光流 | MATLAB实现HS Optical Flow(代码类)
  4. 无监督构建词库:更快更好的新词发现算法
  5. 双向dcdc变换器simulink仿真_台达_OBC双向充电_HighEfficiency HighDensity GaNBased 6.6kW
  6. Java--对象内存布局
  7. java考驾照_基于JavaWeb的驾校考试系统.doc
  8. gitee提交突然报错remote: Incorrect username or password ( access token )
  9. 只需五步,快速构建Python聊天室
  10. 阿里专家:怎么样消除程序员的中年危机?
  11. Matlab学习(可以用MATLAB作曲)
  12. 手机java jdk环境配置文件_JDK怎么安装与配置环境变量
  13. element-ui分页器的使用
  14. Mac 上使用windows软件--wineskin
  15. 音视频开发之旅(41)-天空盒
  16. 报错:undefined symbol: _ZN10tensorflow12OpDefBuilder4AttrESs
  17. 查看详细Windows VISTA 或Windows 7激活状态
  18. 奇异网盘点全球10大最荒诞的“时髦”事件
  19. html中footer怎么写,HTML DOM Footer用法及代码示例
  20. Adobe XD 下载和安装教程

热门文章

  1. Revit插件应用 | 南方yi院增城分院二期建设项目:BIM设计集成应用
  2. 【杂谈】从学员到合作伙伴,我与有三AI不得不说的故事
  3. 带你浅浅了解自动驾驶激光雷达
  4. 【附源码】计算机毕业设计java养生知识平台设计与实现
  5. 论文阅读2 Dynamic Routing Between Capsules
  6. 公有云、私有云、混合云有什么不同?分别适合那些应用场景
  7. Unity地形 使用Mesh网格刷草刷不上的解决方案
  8. jeethink-crm客户关系管理系统
  9. 得到APP之订阅专栏《清华管理学课》和《北大心理学课》目录
  10. canvas绘制海报中文字自动换行