【问题标题】:Audit fields of a class using a class level annotation (aspectj)使用类级别注释 (aspectj) 审计类的字段
【发布时间】:2014-04-17 13:22:56
【问题描述】:

我正在使用 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;
    }
}

观察上面示例中注释的字段分配的方面看起来如何?

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

@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);

    };

}

【问题讨论】:

  • 如果我理解正确你的问题,切入点必须在用@Audit 注释的类的设置器(所有“设置*”方法)上定义。然后,您需要检查方法名称是否与 @Audit 参数中的字段匹配,然后处理新值。也许有一种方法可以在我不知道的字段上添加观察者。

标签: java aspectj


【解决方案1】:

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

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

如果正在修改可审计字段,您必须检查连接点。

【讨论】:

    【解决方案2】:

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

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

    package de.scrum_master.app;
    
    import java.lang.annotation.*;
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target({ElementType.FIELD})
    public @interface Audit {}
    

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

    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 字段。这允许在每个字段的基础上进行细粒度的审计。此外,如果您想在数据库中记录任何内容并审核数据库,您将拥有所需的一切:字段类型和名称、类名等。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-12-30
      • 2016-10-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多