AOP

A programming paradigm that enables the management of common functionalities (cross-cutting concerns) separate from the core business logic, by modularizing them into an “Aspect.”

  • Core concept here is Separation of Concerns
  • Applying AOP allows defining common functionalities in one place, automatically “woven” into the necessary core logic
  • Limitations of OOP
    • OOP separates responsibilities by roles (classes/modules).
    • Repetitive logic like logging, security, transactions, and timing often appears across modules. This logic gets scattered and duplicated.
    • OOP struggles to eliminate such cross-cutting concerns cleanly
  • Cross-Cutting Concerns
    • functionalities that are not directly related to business logic but appear repetitively across multiple layers or components AOP reduces this
    • Examples
      • Transaction (very good w/ AOP)
      • Logging
      • Security
      • Checking performance

Example

Before AOP

@Service
public class MemberService {
 
    private final MemberRepository memberRepository;
 
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
 
    public void join(Member member) {
        long start = System.currentTimeMillis(); // Non-core logic
 
        try {
            // Core Logic
            memberRepository.save(member);
        } finally {
            long end = System.currentTimeMillis(); // Non-core logic
            long time = end - start;
            System.out.println("MemberService.join execution time = " + time + "ms"); // Non-core logic
        }
    }
}
  • Core logic and supplementary logic are mixed within a single source code file.
  • The join() method contains execution time measurement code mixed with its core logic (saving a member).
  • If this logic is repeated across multiple methods or classes, it increases duplication, making maintenance difficult.

After AOP

// Core Logic Class
@Service
public class MemberService {
 
    private final MemberRepository memberRepository;
 
    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }
 
    public void join(Member member) {
        memberRepository.save(member); // Pure core logic
    }
}
 
// Common functionality (here, logging execution time) separated
@Aspect // Marks this class as an Aspect
@Component // Registers this Aspect as a Spring Component/Bean
public class TimeTraceAspect {
 
    // Specifies where this advice should be applied (all methods in 'com.example' and its sub-packages)
    @Around("execution(* com.example..*(..))")
    public Object trace(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis(); // Common functionality
 
        try {
            return joinPoint.proceed(); // Executes the actual target method
        } finally {
            long end = System.currentTimeMillis(); // Common functionality
            long time = end - start;
            System.out.println("[Execution Time] " + joinPoint.getSignature() + " = " + time + "ms"); // Common functionality
        }
    }
}
  • Core logic and supplementary logic can be completely separated.
  • Common functionalities are managed in one place, greatly improving maintainability and extensibility.

AOP in Spring

Summary

Spring supports @AspectJ style AOP and primarily provides proxy-based AOP from the full AspectJ capabilities.

  • Advice
    • Supplementary functionalities (e.g., start the timer)
  • Proxy-based AOP implementation
    • It creates and provides a proxy for the target object.
    • At runtime, Spring creates a proxy object that wraps the target object (e.g., your MemberService).
    • When a method on the proxy is called, the proxy can execute the advice before or after delegating the call to the original target object.
  • Method Join Points Only
    • Advice can only be applied at runtime when the core functionality’s (target object’s) method is called.

Key Components

TermDescription
AspectA module that defines a cross-cutting concern.
- In Spring, this is typically a separate class annotated with @Aspect.
- It contains both the Advice (the “what”) and the Pointcut (the “where”).
- E.g., logging, transactions.
Join PointAn execution point in your code where the Advice could be applied
- In Spring AOP, this is always the execution of a method
- e.g., the exact moment memberService.join() is called
AdviceThe actual code that is executed for the cross-cutting concern
- The specific code for the extra action (e.g., logging, printing, security, etc.
- Also says when to do it (e.g., @Around the method).
- E.g., @Before, @After, @Around, @AfterReturning, @AfterThrowing.
PointcutAn expression that selects the Join Points where the Advice should be applied.
- Acts as a filter.
- E.g., execution(* com.example..*(..)) is a pointcut that matches all method executions in the com.example package and its sub-packages.
WeavingThe process of linking the Aspect with the target object to create the final proxied object.
- In Spring AOP, weaving happens at runtime when the application starts.
  • 꼭 알아야할것
    • aspect
    • join point
    • advice
    • pointcut