Spring AOP - Lập trình hướng khía cạnh trong Spring

AOP - Phương pháp lập trình mới

Spring AOP là một tính năng cốt lõi của framework Spring, cho phép xử lý các mối quan tâm chéo (cross-cutting concerns) như logging, security, transaction management. Bài viết này trình bày các nguyên lý cơ bản và cách triển khai AOP trong Spring.

Khái niệm cơ bản

AOP (Aspect Oriented Programming) giải quyết vấn đề phân tách logic nghiệp vụ chính với các chức năng phụ trợ chung. Thay vì phải sao chép mã lặp đi lặp lại ở nhiều nơi như kiểm tra quyền, ghi log, AOP cho phép tập trung xử lý các chức năng này tại một điểm duy nhất.

Các thành phần chính

  • Advice: Xác định hành vi bổ sung và thời điểm thực thi
  • Pointcut: Quy định vị trí cụ thể trong ứng dụng để áp dụng advice
  • Aspect: Tổ hợp giữa advice và pointcut
  • Join point: Các điểm trong chu trình ứng dụng có thể gắn aspect (thường là các method invocation)
  • Weaving: Quá trình tích hợp aspect vào ứng dụng

Ví dụ minh họa

Tạo dự án Spring Boot với dependency:

implementation 'org.springframework.boot:spring-boot-starter-aop'

Giao diện xử lý nghiệp vụ:

public interface OrderService {
String placeOrder(int amount);
}

Cài đặt cụ thể:

@Service
public class ElectronicsOrder implements OrderService {
@Override
public String placeOrder(int amount) {
System.out.println("Processing order with " + amount + " items");
return "Electronics";
}
}

Tạo aspect xử lý logic chung:

@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.OrderService.placeOrder(..))")
public void logOrderPlacement() {
System.out.println("Order placement started at " + new Date());
}
}

Các loại Advice

Spring AOP hỗ trợ 5 loại advice:

  1. @Before: Chạy trước method chính
  2. @After: Chạy sau method bất kể kết quả
  3. @AfterReturning: Chạy sau khi method thành công
  4. @AfterThrowing: Xử lý khi có exception
  5. @Around: Bao bọc method chính để xử lý trước/sau

Truyền tham số trong Advice

Để truy cập tham số method gốc:

@Around("execution(String com.example.service.OrderService.placeOrder(int)) && args(amount)")
public String handleOrder(ProceedingJoinPoint pjp, int amount) throws Throwable {
if (amount > 100) {
System.out.println("Applying bulk discount");
}
return (String) pjp.proceed();
}

Cấu hình qua XML

Định nghĩa aspect trong file XML:

<aop:config proxy-target-class="true">
<aop:aspect id="logging" ref="loggingAspect">
<aop:before pointcut="execution(* com.example.service.*.*(..))" method="log"/>
</aop:aspect>
</aop:config>

Cơ chế Proxy

  • JDK Dynamic Proxy: Dùng interface làm cơ sở tạo proxy (proxyTargetClass=false)
  • CGLIB: Tạo subclass runtime để hỗ trợ class cụ thể (proxyTargetClass=true)

Thẻ: Spring AOP aspectj proxy XML

Đăng vào ngày 5 tháng 7 lúc 19:54