Simplify Audit Fields in Spring Boot with AOP: Auto‑Fill Creator & Timestamps

This article demonstrates how to use Spring Boot's AOP features to automatically populate common audit columns such as creator, creation time, updater, and update time during DAO insert and update operations, eliminating repetitive manual SQL handling.

Programmer DD
Programmer DD
Programmer DD
Simplify Audit Fields in Spring Boot with AOP: Auto‑Fill Creator & Timestamps

Background

During database design, common fields like creator, createTime, updater, and updateTime are often added to every table for logging. Manually setting these fields in SQL is tedious, especially with many tables. Spring's AOP can automate this process. This article shows how to use Spring Boot AOP to automatically fill these audit fields.

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 Explanation and Annotation Details

1. Code Overview

The aspect class CommonDaoAspect defines pointcuts for DAO update and insert methods and around advice to set creator/updater and timestamps. It obtains the current username from a utility class and uses BeanUtils to set properties on method arguments before proceeding.

2. Annotation Explanation

@Aspect

: declares the class as an aspect containing pointcuts and advice. @Component: registers the class as a Spring-managed bean. @Pointcut: defines where the advice should be applied; here it matches methods in the DAO package whose names start with insert or update. @Around: surrounds the matched method, allowing pre‑ and post‑processing to inject audit information.

Note: The pointcut expression execution(* com.xx.xxxx.*.dao.*.update*(..)) matches any method in the dao package that starts with "update". Similarly, execution(* com.xx.xxxx.*.dao.*.insert*(..)) matches methods starting with "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.

JavaaopdatabaseSpring BootAudit Fields
Programmer DD
Written by

Programmer DD

A tinkering programmer and author of "Spring Cloud Microservices in Action"

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.