审核属性更改 - Spring MVC + JPA

Ira*_*kli 11 java spring jpa audit-logging

我有一个班级客户.我希望能够审计这个类的属性的变化(不是整个类 - 只是它的属性).

public class Client {
private Long id;
private String firstName;
private String lastName;
private String email;
private String mobileNumber;
private Branch companyBranch;
Run Code Online (Sandbox Code Playgroud)

实际上,使用@Audited注释审核整个实体非常容易.

但我想要的是使用我的类结构审核这些更改.

这是我想要的结果类:

public class Action {
private String fieldName;
private String oldValue;
private String newValue;
private String action;
private Long modifiedBy;
private Date changeDate;
private Long clientID;
Run Code Online (Sandbox Code Playgroud)

结果应如下所示:

fieldName +"已从"+ oldValue +"更改为"+ newValue +","clientID +"更改为"modifiedBy;

  • 乔治的比尔盖茨将mobileNumber从555改为999.

我这样做的原因是我需要将这些更改存储到Action表下的DB中 - 因为我将来自不同实体的审核属性,我想将它们存储在一起,然后有能力在需要时获取它们.

我怎样才能做到这一点?

谢谢

Ser*_*lov 8

Aop是正确的方法.您可以将AspectJ与字段set()切入点一起使用以满足您的需求.使用before方面,您可以提取必要的信息以填充Action对象.

您还可以使用自定义类Annotation @AopAudit来检测要审核的类.您必须在类路径中定义此类注释,并将其放在要审核的目标类下.

这种方法看起来像这样:

AopAudit.java

@Retention(RUNTIME)
@Target(TYPE)
public @interface AopAudit {

}
Run Code Online (Sandbox Code Playgroud)

Client.java

@AopAudit
public class Client {
    private Long id;
    private String firstName;
    private String lastName;
    private String email;
    private String mobileNumber;
}
Run Code Online (Sandbox Code Playgroud)

AuditAnnotationAspect.aj

import org.aspectj.lang.reflect.FieldSignature;

import java.lang.reflect.Field;

public aspect FieldAuditAspect {

pointcut auditField(Object t, Object value): set(@(*.AopAudit) * *.*) && args(value) && target(t);

pointcut auditType(Object t, Object value): set(* @(*.AopAudit) *.*) && args(value) && target(t);

before(Object target, Object newValue): auditField(target, newValue) || auditType(target, newValue) {
        FieldSignature sig = (FieldSignature) thisJoinPoint.getSignature();
        Field field = sig.getField(); 
        field.setAccessible(true);

        Object oldValue;
        try
        {
            oldValue = field.get(target);
        }
        catch (IllegalAccessException e)
        {
            throw new RuntimeException("Failed to create audit Action", e);
        }

        Action a = new Action();
        a.setFieldName(sig.getName());
        a.setOldValue(oldValue == null ? null : oldValue.toString());
        a.setNewValue(newValue == null ? null : newValue.toString());
    }

}
Run Code Online (Sandbox Code Playgroud)

这是AspectJ方面,它定义了auditField用于捕获字段集操作的切入点和before用于创建Audit对象的逻辑.

为了使AspectJ Compile Time Weaving您能够在以下情况下执行以下操作Maven:

的pom.xml

...

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
    </dependency>
</dependencies>

...

<plugins>
    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.6</version>
        <configuration>
            <showWeaveInfo>true</showWeaveInfo>
            <source>${java.source}</source>
            <target>${java.target}</target>
            <complianceLevel>${java.target}</complianceLevel>
            <encoding>UTF-8</encoding>
            <verbose>false</verbose>
            <XnoInline>false</XnoInline>
        </configuration>
        <executions>
            <execution>
                <id>aspectj-compile</id>
                <goals>
                    <goal>compile</goal>
                </goals>
            </execution>
            <execution>
                <id>aspectj-compile-test</id>
                <goals>
                    <goal>test-compile</goal>
                </goals>
            </execution>
        </executions>
        <dependencies>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjrt</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
            <dependency>
                <groupId>org.aspectj</groupId>
                <artifactId>aspectjtools</artifactId>
                <version>${aspectj.version}</version>
            </dependency>
        </dependencies>
    </plugin>
</plugins>
Run Code Online (Sandbox Code Playgroud)

Maven配置使AspectJ编译器能够对类进行字节码后处理.

applicationContext.xml中

<bean class="AuditAnnotationAspect" factory-method="aspectOf"/>
Run Code Online (Sandbox Code Playgroud)

此外,您可能需要将方面实例添加到Spring Application Context以进行依赖项注入.

UPD: 以下是此类AspectJ项目配置的示例

  • @Purmarili [这里](https://github.com/sbespalov/aop-aspectj-examples)是一个例子 (2认同)