使用AOP+Annotation实现操作日志记录
先创建注解 OperInfo
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface OperInfo {
public String description() default "";//操作说明
}
然后创建AOP的切面类 LogAspect
public class LogAspect {
@Resource
private OperationLogService operService;
public Object doAroundMethodForCtLog(ProceedingJoinPoint pjp)
throws Throwable{
Method method = getMethod(pjp);
if(method != null && method.isAnnotationPresent(OperInfo.class)){
OperInfo annotation = method.getAnnotation(OperInfo.class);
String descpTemp = annotation.description();
String description = executeTemplate(descpTemp, pjp);
HttpServletRequest request = HttpServletUtils.getRequest();
Users user = (Users) request.getSession().getAttribute("users");
OperationLog operation = new OperationLog();
operation.setChangetime(new Date());
operation.setChangeuserid(user.getUsersid());
operation.setOptid(UUIDUtils.getUUID());
operation.setDescription("用户:"+ user.getUsername() +",日志信息:【{"+description+"}】");
operService.insertService(operation);
}
return pjp.proceed();
}
//解析SPEL
private String executeTemplate(String template, ProceedingJoinPoint joinPoint){
LocalVariableTableParameterNameDiscoverer parameterNameDiscovere = new LocalVariableTableParameterNameDiscoverer();
Method method = getMethod(joinPoint);
String[] parameterNames = parameterNameDiscovere.getParameterNames(method);
EvaluationContext context = new StandardEvaluationContext();
ExpressionParser parser = new SpelExpressionParser();
Object[] args = joinPoint.getArgs();
if(args.length == parameterNames.length){
for (int i = 0,len = args.length; i < len; i++) {
context.setVariable(parameterNames[i], args[i]);
}
}
return parser.parseExpression(template, new TemplateParserContext()).getValue(context, String.class);
}
private Method getMethod(ProceedingJoinPoint joinPoint){
Object target = joinPoint.getTarget();
Method method = ((MethodSignature)joinPoint.getSignature()).getMethod();
try {
method = target.getClass().getMethod(method.getName(), method.getParameterTypes());
} catch (Exception e) {
e.printStackTrace();
}
return method;
}
}
spring-mvc.xml配置
<bean class="com.aop.LogAspect" id="logAspect" />
<aop:config expose-proxy="true">
<aop:pointcut expression="execution(* com.service.impl.*Impl.*(..))" id="txPointcut"/>
<aop:aspect ref="logAspect" >
<aop:around method="doAroundMethodForCtLog" pointcut-ref="txPointcut" />
</aop:aspect>
</aop:config>
最后在需要拦截的service上加上注解就行了
@OperInfo(description="新增了名为#{#user.username}的用户")
public int insertUser(Users user){
}
使用AOP+Annotation实现操作日志记录的更多相关文章
- 微软企业库5.0 学习之路——第九步、使用PolicyInjection模块进行AOP—PART4——建立自定义Call Handler实现用户操作日志记录
在前面的Part3中, 我介绍Policy Injection模块中内置的Call Handler的使用方法,今天则继续介绍Call Handler——Custom Call Handler,通过建立 ...
- 来一手 AOP 注解方式进行日志记录
系统日志对于定位/排查问题的重要性不言而喻,相信许多开发和运维都深有体会. 通过日志追踪代码运行状况,模拟系统执行情况,并迅速定位代码/部署环境问题. 系统日志同样也是数据统计/建模的重要依据,通过分 ...
- Winform开发框架之权限管理系统改进的经验总结(4)-一行代码实现表操作日志记录
在前面介绍了几篇关于我的权限系统改进的一些经验总结,本篇继续这一系列主体,介绍如何一行代码实现重要表的操作日志记录.我们知道,在很多业务系统里面,数据是很敏感的,特别对于一些增加.修改.删除等关键的操 ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- .NetCore中使用AspectCore、ExceptionLess 实现AOP操作日志记录
结合前面封装的ExceptionLess,接下来使用 AspectCore 实现AOP日志处理 nuget导入AspectCore.Core .AspectCore.Extensions.Depend ...
- Spring Boot分布式系统实践【基础模块构建3.3】注解轻松实现操作日志记录
日志注解 前言 spring切面的编程,spring中事物处理.日志记录常常与pointcut相结合 * * Pointcut 是指那些方法需要被执行"AOP",是由"P ...
- springAOP实现操作日志记录,并记录请求参数与编辑前后字段的具体改变
本文为博主原创,未经允许不得转载: 在项目开发已经完成多半的情况下,需要开发进行操作日志功能的开发,由于操作的重要性,需要记录下操作前的参数和请求时的参数, 在网上找了很多,没找到可行的方法.由于操作 ...
- springboot—spring aop 实现系统操作日志记录存储到数据库
原文:https://www.jianshu.com/p/d0bbdf1974bd 采用方案: 使用spring 的 aop 技术切到自定义注解上,针对不同注解标志进行参数解析,记录日志 缺点是要针对 ...
- 利用AOP与ToStringBuilder简化日志记录
刚学spring的时候书上就强调spring的核心就是ioc和aop blablabla...... IOC到处都能看到...AOP么刚开始接触的时候使用在声明式事务上面..当时书上还提到一个用到ao ...
随机推荐
- [ASP.NET MVC 小牛之路]12 - Section、Partial View 和 Child Action
概括的讲,View中的内容可以分为静态和动态两部分.静态内容一般是html元素,而动态内容指的是在应用程序运行的时候动态创建的内容.给View添加动态内容的方式可归纳为下面几种: Inline cod ...
- 《Entity Framework 6 Recipes》中文翻译系列 (17) -----第三章 查询之分页、过滤和使用DateTime中的日期部分分组
翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 3-12 分页和过滤 问题 你想使用分页和过滤来创建查询. 解决方案 假设你有如图3 ...
- 跨域资源共享(CORS)在ASP.NET Web API中是如何实现的?
在<通过扩展让ASP.NET Web API支持W3C的CORS规范>中,我们通过自定义的HttpMessageHandler自行为ASP.NET Web API实现了针对CORS的支持, ...
- 基于zipkin分布式链路追踪系统预研第一篇
本文为博主原创文章,未经博主允许不得转载. 分布式服务追踪系统起源于Google的论文“Dapper, a Large-Scale Distributed Systems Tracing Infras ...
- Java接口和抽象类的区别
今天看到项目中,写了一个抽象类,里面有很多方法继承了这类,当调用这个接口时,采用的是这个抽象类去调方法的,当时一想,这个不就是我们说的Java的多态的特征: 继承:存在继承关系的子类和父类 重写:子类 ...
- iOS-SDWebimage底层实现原理
其实有些框架的实现原理,并没有想象中那么难,思想也很简单,主要是更新第三方框架的作者对自己写的代码,进行了多层封装,使代码的可读性降低,也就使得框架看起来比较难.我来实现以下SDWebimage的的曾 ...
- Javascript刷题 》 查找数组元素位置
找出元素 item 在给定数组 arr 中的位置 输出描述: function indexOf(arr, item) { ..... } 如果数组中存在 item,则返回元素在数组中的位置,否则返回 ...
- Nokia 920板砖自救(理论上通用,升级Win10成板砖也可以用这个恢复)
异常处理汇总 ~ 修正果带着你的Net飞奔吧! http://www.cnblogs.com/dunitian/p/4599258.html 个人博客:http://dnt.dkill.net 下载下 ...
- Powershell 切换IE代理
买了一个穿越防火墙的代理,在 Windows 下每次手动设置代理都好麻烦,最后不断尝试 Powershell 来设置,最后也终于成功了. 其实利用 Powershell 来设置 IE 的代理,就是 ...
- js立即执行函数
一.JS立即执行函数的写法 方式1.最前最后加括号 (function(){alert(1);}()); 方式2.function外面加括号 (function(){alert(1);})(); ...