Aspect审核字段更改

时间:2016-10-26 10:45:46

标签: spring-mvc aspectj

我正在尝试使用Aspect审核功能和自定义anotations捕获已归档的更改,但无法获得旧值。 这是我的代码:

public aspect FieldAuditAspect {

@Autowired
ActivityService activityService;
@Autowired
UserService userService;

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

before (Object target, Object newValue): auditField(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);
    }

    System.out.println("changed from " + oldValue + " to " + newValue);
   }

}

这是我用于将所需字段映射到捕获更改的自定义注释:

@Retention(RUNTIME)
@Target(value = { TYPE, FIELD})
public @interface AopAudit {

}

这是我的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>ge.shemo</groupId>
<artifactId>SHEMOProject</artifactId>
<version>1.0</version>
<packaging>war</packaging>


<properties>
    <java.version>1.8</java.version>
    <junit.version>4.11</junit.version>
    <slf4j.version>1.7.5</slf4j.version>
    <logback.version>1.0.13</logback.version>
    <spring.version>4.1.9.RELEASE</spring.version>
    <aspectj.version>1.8.2</aspectj.version>
    <java.source>1.8</java.source>
    <java.target>1.8</java.target>
    <spring-security.version>3.2.0.RELEASE</spring-security.version>
    <hibernate.version>5.0.1.Final</hibernate.version>
    <jackson-json.version>2.3.1</jackson-json.version>
    <commons-dbcp.version>1.2.2</commons-dbcp.version>
    <commons-lang3.version>3.1</commons-lang3.version>
</properties>

<build>
    <pluginManagement>
        <plugins>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.5.1</version>
                <configuration>
                    <source>${java.source}</source>
                    <target>${java.target}</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-resources-plugin</artifactId>
                <version>3.0.1</version>
                <configuration>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-source-plugin</artifactId>
                <version>3.0.1</version>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>aspectj-maven-plugin</artifactId>
                <version>1.8</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>
                <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>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.19.1</version>
            </plugin>
        </plugins>
    </pluginManagement>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <executions>
                <execution>
                    <id>aspectj-weave</id>
                    <phase>compile</phase>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>aspectj-weave-test</id>
                    <phase>test-compile</phase>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                    <configuration>
                    </configuration>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <artifactId>maven-compiler-plugin</artifactId>
        </plugin>
    </plugins>
</build>

<dependencies>
    <!-- Logging dependencies -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>${slf4j.version}</version>
    </dependency>

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>

    <!-- Spring dependencies -->


    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context-support</artifactId>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
    </dependency>
    <!-- Spring Data JPA dependencies -->


    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>${hibernate.version}</version>
    </dependency>

    <!-- SpringSecurity dependencies -->
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-core</artifactId>
        <version>${spring-security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>${spring-security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-config</artifactId>
        <version>${spring-security.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-taglibs</artifactId>
        <version>${spring-security.version}</version>
    </dependency>



    <!-- Testing dependencies -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

    <!-- DB dependencies -->


    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>${commons-dbcp.version}</version>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>${jackson-json.version}</version>
    </dependency>

    <dependency>
        <groupId>javax.mail</groupId>
        <artifactId>mail</artifactId>
        <version>1.4.3</version>
    </dependency>

    <!-- Web dependencies -->


    <dependency>
        <groupId>taglibs</groupId>
        <artifactId>standard</artifactId>
        <version>1.1.2</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.0.1.Final</version>
    </dependency>



    <!-- optional -->

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-osgi</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-envers</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-proxool</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-infinispan</artifactId>
        <version>5.0.1.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>5.0.1.Final</version>
    </dependency>

    <dependency>
        <groupId>net.sf.dozer</groupId>
        <artifactId>dozer</artifactId>
        <version>5.5.1</version>
    </dependency>


    <dependency>
        <groupId>joda-time</groupId>
        <artifactId>joda-time</artifactId>
        <version>2.8.2</version>
    </dependency>
    <dependency>
        <groupId>commons-lang</groupId>
        <artifactId>commons-lang</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.3.1</version>
    </dependency>


    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <dependency>
        <groupId>com.microsoft.sqlserver</groupId>
        <artifactId>sqljdbc4</artifactId>
        <version>4.0</version>
    </dependency>

    <dependency>
        <groupId>com.googlecode.json-simple</groupId>
        <artifactId>json-simple</artifactId>
        <version>1.1.1</version>
    </dependency>


    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20151123</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
        <version>2.5</version>
    </dependency>
    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.springframework.data/spring-data-jpa -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>1.7.1.RELEASE</version>
    </dependency>


    <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>4.1.9.RELEASE</version>
    </dependency>



    <!-- https://mvnrepository.com/artifact/com.google.guava/guava -->
    <dependency>
        <groupId>com.google.guava</groupId>
        <artifactId>guava</artifactId>
        <version>19.0</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.sparkpost/sparkpost-lib -->
    <dependency>
        <groupId>com.sparkpost</groupId>
        <artifactId>sparkpost-lib</artifactId>
        <version>0.16.1</version>
    </dependency>


    <!-- scope provided because the processor is only needed for the compiler -->
    <dependency>
        <groupId>fr.xebia.extras</groupId>
        <artifactId>selma-processor</artifactId>
        <version>0.15</version>
        <scope>provided</scope>
    </dependency>

    <!-- This is the only real dependency you will have in your binaries -->
    <dependency>
        <groupId>fr.xebia.extras</groupId>
        <artifactId>selma</artifactId>
        <version>0.15</version>
    </dependency>


    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>${aspectj.version}</version>
    </dependency>


</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>${spring.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

这是我的实体类:

@Entity
@EntityListeners(AuditingEntityListener.class)
public class Client {

@AopAudit
private String firstName;
@AopAudit
private String lastName;
@Enumerated(EnumType.STRING)
private Gender gender;
.....

这是我更新实体的功能:

 public Client saveClient(ClientDTO clientDTO) {

    DozerBeanMapper mapper = new DozerBeanMapper();
    Client client = getClient(clientDTO.getid); //Getting client from DB

    client =  mapper.map(clientDTO, Client.class); //casting DTO to Entity using DozerBeanMapper

    saveClient(client);

一切正常,但我没有得到旧值 - 旧值总是为空。我需要得到旧值来保存它,但不明白为什么我没有得到旧的价值。

有人能告诉我我做错了吗?

我正在使用Spring MVC + JPA

1 个答案:

答案 0 :(得分:3)

让我试着解释一下这应该如何运作。在FieldAuditAspect注释的字段设置操作之前触发@AopAudit,切入点定义中的target(t)表示当前受方面影响的对象实例。

在您的情况下,您执行以下操作:

client =  mapper.map(clientDTO, Client.class);

这意味着mapper创建Client 新实例 ,其中空字段值,然后使用相应的clientDTO字段值填充它。 因此,这里的空old值来自。

按照您的预期进行操作,您应该使用之前提取的Client对象执行相同操作,如下所示:

client =  mapper.map(clientDTO, client);
此处使用的

client对象代替Client.class

如果您这样做,那么您应该会看到old字段值,它存在于已获取的客户端对象中,并与new clientDTO中的{{1}}一起显示。