使用Spring AOP,自定义注释和反射为您的应用审核基础架构

下一篇文章将演示如何使用Spring AOP和注释编写简单的审计。 审核机制将是干净,高效且易于维护的(和Kewwl!)。

我将在用户管理系统上演示我的示例(假设您对反射和AOP具有一般知识)。

我们从简单的数据库表开始,以保​​存我们的审计数据:

`id`,`username``user_type``action``target_user``date``user_ip`

我们需要填充4个主要字段(用户名,用户类型,操作,目标用户)

*用户名–执行操作的用户

* TargetUser –执行操作的目标用户。

现在,让我们创建新的注释以标记我们的“想被审计”方法。 我们将非常“有创意”并使用:@AuditAble

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD,ElementType.TYPE})
public @interface Auditable {
AuditingActionType actionType();
}

带注释的@AuditAble方法示例:

@Override@Transactional@Auditable(actionType = AuditingActionType.INTERNAL_USER_REGISTRATION)public void createInternalUser(UserDTO userDTO) {userCreationService.createInternalUserOnDB(userDTO);}

我们未来的Aspect(aop)将使用DTO从方法参数中收集一些审核数据。 在我们的情况下,将收集目标用户名和actionType作为我们的审核信息。

为此,我创建了另一个注释AuditingTargetUsername

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE})
public @interface AuditingTargetUsername {
String value() default "";
}

因此,在UserDTO内部,我们得到了:

public abstract class UserDTO implements Serializable {@NotNull@AuditingTargetUsernameprivate String userName;...}

我们用@AuditingTargetUsername注释了userName。 该信息将在以后收集。

现在,让我们创建AOP的方面。 此处收集并执行所有审核逻辑(拦截@Auditable方法,从批注中提取信息,使用存储库保存最终审核记录):

@Aspect
public class AuditingAspect {....@After("@annotation(auditable)")@Transactionalpublic void logAuditActivity(JoinPoint jp, Auditable auditable) {String targetAuditingUser;String actionType = auditable.actionType().getDescription();String auditingUsername = Authentication auth = SecurityContextHolder.getContext().getAuthentication().getName()role = userService.getCurrentUser(false).getPermissionsList().toString();auditingUsernameIp = request.getRemoteAddr();}logger.info("Auditing information. auditingUsername=" + auditingUsername + ", actionType=" + actionType + ", role=" + role + ", targetAuditingUser="+ targetAuditingUser + " auditingUsernameIp=" + auditingUsernameIp);auditingRepository.save(new AuditingEntity(auditingUsername, role, actionType, targetAuditingUser, auditingUsernameIp,new Timestamp(new java.util.Date().getTime())));}

ill解释了主要的代码区域:

切入点–所有@ Auditable.annotations
建议–键入@After(我们希望在调用该方法之后进行审核)

通过带注释的方法的声明检索ActionType值:

@Auditable( actionType = AuditingActionType.INTERNAL_USER_REGISTRATION

auditingUsername是执行操作的当前用户(在本例中为登录用户)。 我是通过SecurityContext(Spring Security)检索到的。

现在,我们将通过运行时的反射来提取@targetAuditingUser字段:

targetAuditingUser = extractTargetAuditingUser(jp.getArgs());
...public String extractTargetAuditingUserFromAnnotation(Object obj) {
...result = getTargetAuditingUserViaAnnotation(obj);...}

这就是通过反射提取带注释的字段的逻辑:

private String getTargetAuditingUserViaAnnotation(Object obj) {
class cl=obj.getClass()String result = null;try {for (Field f : cl.getDeclaredFields())for (Annotation a : f.getAnnotations()) {if (a.annotationType() == AuditingTargetUsername.class) {f.setAccessible(true);Field annotatedFieldName = cl.getDeclaredField(f.getName());annotatedFieldName.setAccessible(true);String annotatedFieldVal = (String) annotatedFieldName.get(obj);logger.debug("Found auditing annotation. type=" + a.annotationType() + " value=" + annotatedFieldVal.toString());result = annotatedFieldVal;}}} catch (Exception e) {logger.error("Error extracting auditing annotations from obj" + obj.getClass());}return result;}

DB上的结果:

审核1

而已。 我们拥有干净的审核基础结构,您所需要做的就是用@Auditable注释您的方法,并在DTO /实体内部注释所需的待审核信息。

伊丹

翻译自: https://www.javacodegeeks.com/2014/07/auditing-infrastructure-for-your-app-using-spring-aop-custom-annotations-and-reflection.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/362790.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

经过几天的Scala回归Java的10个最烦人的事情

因此,我正在尝试使用Scala,因为我想编写一个解析器,而Scala Parsers API似乎非常合适。 毕竟,我可以在Scala中实现解析器并将其包装在Java接口后面,因此除了附加的运行时依赖关系之外,不应该存在任何互操作…

检查Red Hat JBoss BRMS部署架构的规则和事件(第二部分)

(文章来宾与北美红帽公司高级中间件顾问约翰赫洛克 ( John Hurlocker)合着) 在本周的技巧中,我们将放慢速度,并仔细研究可能的Red Hat JBoss BRMS部署体系结构。 当我们谈论部署架构时,我们指…

博客园皮肤-我的博客园皮肤设置教程

一、前言 好的博客皮肤能吸引更多的访问量,也可以使博主更有动力更新博客。今天看到一个博主的博客非常漂亮,突发奇想也打扮了一下自己的博客,虽然差距还有不小,也记录一下操作方法供大家参考。 二、操作 1.左上角“fork me on gi…

设计撑百万并发的数据库架构

设计撑百万并发的数据库架构 https://www.toutiao.com/a6742034135486824973/ 前言 作为一个全球人数最多的国家,一个再怎么凄惨的行业,都能找出很多的人为之付出。而在这个互联网的时代,IT公司绝对比牛毛还多很多。但是大多数都是创业公司&a…

Spring MVC集成测试:断言给定的模型属性有全局错误

为了使用Bean验证报告Spring MVC中的全局错误,我们可以创建一个自定义的类级别约束注释。 全局错误与已验证Bean中的任何特定字段都不相关。 在本文中,我将展示如何使用Spring Test编写测试,以验证给定的model属性是否存在全局验证错误。 自…

Tips_一级菜单栏实现

1.纵向 1 <!DOCTYPE html>2 <html lang"en">3 <head>4 <meta charset"UTF-8">5 <title>menu01</title>6 <style type"text/css">7 *{8 margin: 0;9 pad…

2-使用git管理一个单片机程序

https://www.cnblogs.com/yangfengwu/p/10842205.html 我用电脑压缩一个文件,然后通过git上传,然后在新买的linux系统通过wget 网络下载这个压缩文件,然后死活解压不可以...无论是哪种格式的文件 一开始我怀疑是压缩软件压缩的问题,就换了一个压缩软件进行压缩,但是没有解决问题…

Java线程面试的前50个问题,面向初学者和经验丰富的程序员

您可以参加任何Java面试&#xff0c;无论是大四还是中级&#xff0c;经验或新来的人&#xff0c;一定会看到线​​程&#xff0c;并发和多线程中的几个问题。 实际上&#xff0c;这种内置的并发支持是Java编程语言的最强优势之一&#xff0c;并帮助它在企业界和程序员中同样流行…

《写给大家看的Web设计书(第3版)》即将上市

《写给大家看的设计书》姊妹篇——《写给大家看的Web设计书&#xff08;第3版&#xff09;》 即将上市。它是Robin Williams的又一本设计书。 也许大家对Robin Williams的畅销书《写给大家看的设计书》还念念不忘&#xff0c;还在回味那些简单凝练的设计经验。那好&#xff0c;…

VUE+ElementUI 搭建后台项目(一)

前言 之前有些过移动端的项目搭建的文章&#xff0c;感觉不写个pc端管理系统老感觉少了点什么&#xff0c;最近公司项目比较多&#xff0c;恰巧要做一个申报系统的后台管理系统&#xff0c;鉴于对vue技术栈比较熟悉&#xff0c;所以考虑还是使用vue技术栈来做&#xff1b;看过一…

用 .NET 3.5 创建 ToJSON() 扩展方法

今年早些时候&#xff0c;我通过blog介绍了 C# 和 VB 语言的一项新的扩充特性"扩展方法"。 扩展方法让开发者可以向已有的 CLR 类型的公共契约中添加新的方法&#xff0c;而不需要子类化或重新编译原有的类型。通过这种做法&#xff0c;可以使很多有用的应用场景成为…

Java中File的getPath(),getCanonicalPath()和getAbsolutePath()之间的区别

File API在Java中非常重要&#xff0c;因为它使文件系统可以访问Java程序。 尽管Java的文件API丰富&#xff0c;但是使用它们时仍需要了解许多细节。 关于文件路径的常见查询程序员之一是getPath() &#xff0c; getCanonicalPath()和getAbsolutePath()方法之间的区别&#xff…

Docker容器CPU、memory资源限制

背景 在使用 docker 运行容器时&#xff0c;默认的情况下&#xff0c;docker没有对容器进行硬件资源的限制&#xff0c;当一台主机上运行几百个容器&#xff0c;这些容器虽然互相隔离&#xff0c;但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制&…

JS_理解函数参数按值传递

本文是我基于红宝书《Javascript高级程序设计》中的第四章&#xff0c;4.1.3传递参数小节P70&#xff0c;进一步理解javaSript中函数的参数&#xff0c;当传递的参数是对象时的传递方式。 &#xff08;结合资料的个人理解&#xff0c;有不正确的地方&#xff0c;希望大家指出&…

检查Red Hat JBoss BRMS部署架构的规则和事件(第一部分)

&#xff08;文章来宾与北美红帽公司高级中间件顾问约翰赫洛克 &#xff08; John Hurlocker&#xff09;合着&#xff09; 在本周的技巧中&#xff0c;我们将放慢速度&#xff0c;并仔细研究可能的Red Hat JBoss BRMS部署体系结构。 当我们谈论部署架构时&#xff0c;我们指…

CSS_选择符

2016-10-28 《CSS入门经典》第五章 以下提示注意事项&#xff1a; 1.如何选择使用id选择符还是class选择符&#xff1a;当确信id选择符在页面的唯一性时&#xff0c;就可以使用id选择符。 2.通用选择符在所有元素上设置样式&#xff0c;并不是只设置继承的默认值。 eg&…

TFS2010配置SQLServer2008R2 tf255049错误

TFS2010配置SQLServer2008R2时&#xff0c;配置数据库时提示 tf255049错误。转载于:https://www.cnblogs.com/ShuaiHo/archive/2010/05/12/1733731.html

位运算笔记2.0

声明&#xff1a; 本文为转载文章 转载于:https://www.cnblogs.com/ShineEternal/p/10853132.html

教程–带有Jersey和Spring的Java REST API设计和实现

想要在Java中使用REST&#xff1f; 然后您来对地方了&#xff0c;因为在博客文章中&#xff0c;我将向您介绍如何“美丽”地设计REST API&#xff0c;以及如何使用Jersey框架在Java中实现它。 在本教程中开发的RESTful API将为存储在MySql数据库中的播客资源演示完整的Create&a…

ie6 下最佳 PNG透明方案【转】

“咳! 哎!….. ” 你听见了么? 这些都是大家抱怨IE6下不能实现png图片漂亮的明效果的哀叫声,的确是无奈呀….. 不过现在幸运的是,我们能够让这一切的抱怨都停止. 网络上解决IE6下Png透明解决方案有很多,例如 IE PNG Fix from TwinHelix, Javascript IE PNG Fix, Transparent …