🌱 Spring AOP (Aspect-Oriented Programming) – Complete Notes

📌 1. What is AOP?

Aspect-Oriented Programming (AOP) is a programming paradigm used to separate cross-cutting concerns from the main business logic.

Cross-Cutting Concerns Examples:

🧠 2. Why Use AOP?

Without AOP:

public void transferMoney() {
    log.info("Start transfer");
    checkSecurity();
    // business logic
    log.info("End transfer");
}

With AOP:

public void transferMoney() {
    // pure business logic only
}

🧩 3. Core Terminology

TermDescription
AspectA class that contains cross-cutting logic
Join PointA point during execution
AdviceAction taken at a join point
PointcutExpression that selects join points
WeavingLinking aspects with application code

🔥 4. Difference Between JoinPoint and Pointcut

FeatureJoinPointPointcut
Definition A specific point in program execution An expression that selects join points
Nature Actual event Selection rule
Usage Used inside advice Used to define matching logic

🔥 4A. Difference Between JoinPoint and ProceedingJoinPoint

FeatureJoinPointProceedingJoinPoint
Definition Represents a point during execution Special JoinPoint used in @Around advice
Control Cannot control execution Can control execution
Execution Only observe Can execute using proceed()
Usage @Before, @After @Around only

Example:

@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint pjp) throws Throwable {
    System.out.println("Before method");
    Object result = pjp.proceed();
    System.out.println("After method");
    return result;
}

🎯 5. Types of Advice

Advice TypeWhen It RunsDescription
@BeforeBefore method executionRuns before the target method executes
@AfterAfter method executionRuns after method completes (both success and exception)
@AfterReturningAfter successful executionRuns only when method completes successfully
@AfterThrowingWhen exception occursRuns only if method throws an exception
@AroundBefore + AfterWraps the method and controls execution

Examples:

@Before("execution(* com.example.service.*.*(..))")
public void beforeAdvice() {
    System.out.println("Before method");
}

@After("execution(* com.example.service.*.*(..))")
public void afterAdvice() {
    System.out.println("After method");
}

@AfterReturning("execution(* com.example.service.*.*(..))")
public void afterReturningAdvice() {
    System.out.println("After successful execution");
}

@AfterThrowing("execution(* com.example.service.*.*(..))")
public void afterThrowingAdvice() {
    System.out.println("Exception occurred");
}