Search code examples
javaspring-bootaop

Multiple Audit table by using AOP and Spring Boot


I want to create audit aspect that will store different auditing by some main entity type as per design. I have created annotation like @Auditing where I defined audit type variable. That will annotated at method level. Where do I add logic for which audit table use for main entity in aspect design?

Just example:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Auditing {

   Event event();
}

Aspect design:

@Aspect
@Component
public class AuditAspect {

    @AfterReturning(value = "@annotation(auditable)")
    public void save(Auditing audit) {

        Audit auditInfo = new Audit();
        // I plan to add some condition here by entity type
    }
}

I plan to add some condition after audit entity create like ‘Which table is used for audit store by type’? Is this good?


Solution

  • If you're worried about performance, from my knowledge Aspect code is weaved into your own code only once during application bootstrapping so there's no problem there.

    Essentially a method like this:

    @Auditing
    public void test(){
      // method logic
    }
    

    becomes

    @Auditing
    public void test(){
       Audit auditInfo = new Audit();
      // extra auditing logic...
    
      // method logic
    }
    

    so as long as the aspect method body isn't something with a long execution time you shouldn't have a problem. However if the auditing aspect also accesses the database and your Audited methods are being frequently called you might have a big overhead. It would probably be better to add all the audit updates in a collection and periodically execute them in a batch manner.

    Now regarding where you should put the table assertion code, my opinion is inside the aspect. Otherwise you'd have to create different aspects for each table which beats the point in the first place. However, please check if you can actually pass the table name as an annoatation parameter and access it inside your aspect.

    What you'd ideally want is:

    @Auditing(tableName="AUDIT_TABLE_1")
    public void auditableMethod() {
      // logic
    }
    
    @Aspect
    public void audit(Auditing audit) {
      String table = audit.tableName;
      // do your jdbc logic
    }