Auto‑populate Audit Fields in Spring Boot with AOP: A Step‑by‑Step Guide

Learn how to use Spring Boot’s AOP features to automatically fill creator, creation time, updater, and update time fields for any DAO insert or update operation, eliminating repetitive code and ensuring consistent audit logging across all database tables.

ITFLY8 Architecture Home
ITFLY8 Architecture Home
ITFLY8 Architecture Home
Auto‑populate Audit Fields in Spring Boot with AOP: A Step‑by‑Step Guide

Background

In database design it is common to add generic fields such as creator, createTime, updater, updateTime to every table for basic audit logging. Manually setting these fields in every SQL statement becomes verbose, especially with many tables. Spring’s AOP can automate this process.

Core Code

@Aspect
@Component
@Configuration
public class CommonDaoAspect {
    private static final String creater = "creater";
    private static final String createTime = "createTime";
    private static final String updater = "updater";
    private static final String updateTime = "updateTime";

    @Pointcut("execution(* com.xx.xxxx.*.dao.*.update*(..))")
    public void daoUpdate() {}

    @Pointcut("execution(* com.xx.xxxx.*.dao.*.insert*(..))")
    public void daoCreate() {}

    @Around("daoUpdate()")
    public Object doDaoUpdate(ProceedingJoinPoint pjp) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return pjp.proceed();
        }
        HttpServletRequest request = attributes.getRequest();
        String token = request.getHeader("token");
        String username = getUserName();
        if (token != null && username != null) {
            Object[] objects = pjp.getArgs();
            if (objects != null && objects.length > 0) {
                for (Object arg : objects) {
                    BeanUtils.setProperty(arg, updater, username);
                    BeanUtils.setProperty(arg, updateTime, new Date());
                }
            }
        }
        Object object = pjp.proceed();
        return object;
    }

    @Around("daoCreate()")
    public Object doDaoCreate(ProceedingJoinPoint pjp) throws Throwable {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            return pjp.proceed();
        }
        Object[] objects = pjp.getArgs();
        if (objects != null && objects.length > 0) {
            for (Object arg : objects) {
                String username = getUserName();
                if (username != null) {
                    if (StringUtils.isBlank(BeanUtils.getProperty(arg, creater))) {
                        BeanUtils.setProperty(arg, creater, username);
                    }
                    if (StringUtils.isBlank(BeanUtils.getProperty(arg, createTime))) {
                        BeanUtils.setProperty(arg, createTime, new Date());
                    }
                }
            }
        }
        Object object = pjp.proceed();
        return object;
    }

    private String getUserName() {
        return UserUtils.getUsername();
    }
}

Code Introduction

The aspect defines four constant field names and two pointcuts that match any DAO method whose name starts with insert or update. The @Around advice populates the audit fields before the original DAO method executes.

Annotation Explanation

@Aspect: declares the class as an aspect containing pointcuts and advice.

@Component: registers the class as a Spring bean.

@Pointcut: defines where the aspect applies, here matching DAO methods with insert or update in their names.

@Around: surrounds the matched method, allowing us to add or modify parameters before and after execution.

Note: execution(* com.xx.xxxx..dao..update*(..)) matches any method under the dao package that starts with update, and similarly for insert.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaaopSpring BootaspectjAudit logging
ITFLY8 Architecture Home
Written by

ITFLY8 Architecture Home

ITFLY8 Architecture Home - focused on architecture knowledge sharing and exchange, covering project management and product design. Includes large-scale distributed website architecture (high performance, high availability, caching, message queues...), design patterns, architecture patterns, big data, project management (SCRUM, PMP, Prince2), product design, and more.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.