我正在用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);
};
}
答案 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字段。这允许在每个字段的基础上进行细粒度审计。此外,如果您想要记录任何内容并审核数据库,请提供所需的一切:字段类型和名称,类名等。