Backend Development 14 min read

Implementing Business Operation Logging with Spring AOP in a Spring Boot Application

This article explains how to design and implement a business operation logging feature using Spring AOP in a Spring Boot project, covering requirement analysis, anti‑pattern pitfalls, AOP design, environment and dependency setup, database schema, annotation and aspect code, and testing procedures.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Implementing Business Operation Logging with Spring AOP in a Spring Boot Application

Preface

The author finally writes about a simple requirement—recording and querying business operation logs—while recalling a poorly implemented solution that motivated the redesign.

Requirement Description and Analysis

Clients need to log who performed which operation, when, the request and response payloads, and optionally allow a one‑click rollback.

System Log

System logs capture program execution steps (debug, info, warn, error) for developers or ops to troubleshoot issues.

Operation Log

Operation logs record actual business actions (user, time, function, type, description, request/response messages) and are stored in a database for users or administrators.

Key functional requirements:

Record fields: operator, time, function, log type, description, request message, previous message.

Provide a visual page for querying and tracing important operations.

Allow rollback of erroneous operations when needed.

Anti‑pattern Implementation

The initial approach hard‑coded log collection in every controller method, duplicated code, and tightly coupled logging with business logic, making maintenance painful.

@RestController
@Slf4j
@BusLog(name = "Personnel Management")
@RequestMapping("/person")
public class PersonController2 {
    @Autowired
    private IPersonService personService;
    @Autowired
    private IBusLogService busLogService;
    // add person
    @PostMapping
    public Person add(@RequestBody Person person) {
        try {
            Person result = this.personService.registe(person);
            this.saveLog(person);
            log.info("// add person completed");
        } catch (Exception e) {
            this.saveExceptionLog(e);
        }
        return result;
    }
}

Design Idea

Using AOP is the clean solution:

Define a custom annotation @BusLog with attributes such as function name and description.

Annotate target methods (or classes) that require logging.

Create a pointcut for methods annotated with @BusLog and implement an aspect that records the log after method execution.

Spring AOP

AOP allows adding cross‑cutting concerns without modifying source code, providing fine‑grained control (before, after, around, exception, return) and can be applied at controller or service layers.

Filter and HandlerInterceptor

Filters and interceptors are limited to servlet environments and cannot modify request/response payloads, whereas Spring AOP works across any layer.

Comparison

Scope: Filter → servlet container; Interceptor → Spring MVC; Spring AOP → any Spring bean.

Granularity: Filter (coarse), Interceptor (pre/post), Spring AOP (most fine‑grained, can alter return values).

Implementation Plan

Environment Configuration

JDK 1.8, IntelliJ IDEA 2020.1

Spring Boot 2.3.9.RELEASE

mybatis-spring-boot-starter 2.1.4

Dependency Configuration

org.springframework.boot
spring-boot-starter-aop

Table Structure Design

create table if not exists bus_log (
    id bigint auto_increment comment '自增id' primary key,
    bus_name varchar(100) null comment '业务名称',
    bus_descrip varchar(255) null comment '业务操作描述',
    oper_person varchar(100) null comment '操作人',
    oper_time datetime null comment '操作时间',
    ip_from varchar(50) null comment '操作来源ip',
    param_file varchar(255) null comment '操作参数报文文件'
) comment '业务操作日志' default charset='utf8';

Code Implementation

1. Define the @BusLog annotation.

/**
 * Business log annotation
 */
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BusLog {
    String name() default ""; // function name
    String descrip() default ""; // description
}

2. Annotate controller methods.

@RestController
@Slf4j
@BusLog(name = "Personnel Management")
@RequestMapping("/person")
public class PersonController {
    @Autowired
    private IPersonService personService;
    @PostMapping
    @BusLog(descrip = "Add a single person")
    public Person add(@RequestBody Person person) {
        Person result = personService.registe(person);
        log.info("// add person completed");
        return result;
    }
    // other CRUD methods similarly annotated
}

3. Implement the aspect that writes log entries and saves request payloads to files.

@Component
@Aspect
@Slf4j
public class BusLogAop implements Ordered {
    @Autowired
    private BusLogDao busLogDao;

    @Pointcut("@annotation(com.fanfu.anno.BusLog)")
    public void pointcut() {}

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object result = pjp.proceed();
        // retrieve annotation info, serialize arguments, write to file, insert DB record
        return result;
    }

    @Override
    public int getOrder() { return 1; }
}

Testing

Debugging Method

Use IntelliJ IDEA's built‑in HTTP client (Tools → HTTP Client → Test RESTful Web Service) as an alternative to Postman.

Verification Result

Screenshot examples show successful requests and logged entries.

Conclusion

The business operation log captures function name, description, operator, timestamp, and parameter payloads; storing payloads in files keeps the database lightweight while still enabling precise rollback when needed.

backendJavaaopSpring BootMyBatisBusiness Logging
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login 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.