使用类级别注释(aspectj)审计类的字段

时间:2014-04-17 13:22:56

标签: java aspectj

我正在用aspectj编写一个简单的审计框架,它允许我审计用@Audit注释注释的类的字段。 作为值,@ Audit注释需要监视一组字段名称

示例用法:

@Audit({"name","phoneNumber"})
class User {

    private String name;

    private String phoneNumber;

    public getName(){
        return name;
    };

    public setName(String name){
        this.name=name;
    }
}

Aspect看起来如何监视如上例所示的注释字段的分配?

这是我第一次尝试的存根:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Audit {
    String[] value()
}

@Aspect
class AuditAspect {

    @Pointcut("????")
    public void markedFieldWasModified(){}

    @AfterReturning("markedFieldWasModified()")
    public void addFieldToModifiedFields(JoinPoint jp, AuditableEO eo){
        eo.addModifiedField(jp.getSignature().getName());
    }

    // inter Type declarations
    public interface IAuditableEO {
        public Iterator<String> modifiedFields();

        public boolean modified();

        public boolean addModifiedField(String field);

    };

}

2 个答案:

答案 0 :(得分:0)

根据https://eclipse.org/aspectj/doc/next/quick5.pdf

你应该可以set(* *.*) && @target(Audit)

然后,如果正在修改可审核字段,则必须检查连接点。

答案 1 :(得分:0)

如何不过度设计整个事物并直接注释字段而不是类?你也可以跳过IAuditableEO接口IMO,我看不出它为什么会有用。这是一个类似于你的简单示例,只是代码风格的语法方面(为了清晰起见,我更喜欢注释式语法,但你可以自己轻松转换它):

审核字段(不是类)的注释:

package de.scrum_master.app;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Audit {}

带有示例主方法的用户类:

package de.scrum_master.app;

public class User {
    private int id;
    @Audit private String name;
    @Audit private String phoneNumber;

    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getPhoneNumber() { return phoneNumber; }
    public void setPhoneNumber(String phoneNumber) { this.phoneNumber = phoneNumber; }

    public static void main(String[] args) {
        User user = new User();
        user.setId(11);
        user.setName("John Doe");
        user.setPhoneNumber("+49-1111-23456789");
        System.out.println("User(" + user.getId() + ", " + user.getName() + ", " + user.getPhoneNumber() + ")");
    }
}

审核方面:

package de.scrum_master.aspect;

import de.scrum_master.app.Audit;

public aspect AuditAspect {
    pointcut fieldModification() : set(@Audit * *);

    after() : fieldModification() {
        System.out.println(thisJoinPointStaticPart);
    }
}

示例输出:

set(String de.scrum_master.app.User.name)
set(String de.scrum_master.app.User.phoneNumber)
User(11, John Doe, +49-1111-23456789)

如您所见,只捕获带注释的字段,而不是ID字段。这允许在每个字段的基础上进行细粒度审计。此外,如果您想要记录任何内容并审核数据库,请提供所需的一切:字段类型和名称,类名等。