Advice Types in AOP

Advice = What action should run + When it should run


1. @Before Advice

Runs BEFORE the actual method executes

Code Example

@Aspect
@Component
class LoggingAspect {

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

Flow

Client → Proxy → @Before → Actual Method

Use Cases

  • Logging (start of method)
  • Security checks
  • Input validation

Important Behavior

  • Cannot stop method execution
  • Cannot access return value
  • Cannot modify output

Mental Model

👉 “Before doing anything, run this logic”


2. @After Advice

👉 Runs AFTER method execution (always)

  • Whether success or exception

Code Example

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

Flow

Client → Proxy → Method → @After

Use Cases

  • Cleanup
  • Logging completion
  • Resource release

Important Behavior

  • Runs even if exception occurs
  • No access to return value

Mental Model

“No matter what happens, run this”


3. @AfterReturning Advice

👉 Runs ONLY when method executes successfully

Code Example

@AfterReturning(
    pointcut = "execution(* com.app.service.*.*(..))",
    returning = "result"
)
public void afterSuccess(Object result) {
    System.out.println("Returned: " + result);
}

Flow

Client → Proxy → Method → SUCCESS → @AfterReturning

Use Cases

  • Logging result
  • Auditing
  • Post-processing

Important Behavior

  • Runs only on success
  • Can access return value
  • Cannot modify execution

Mental Model

👉 “If everything went well, run this”


4. @AfterThrowing Advice

👉 Runs ONLY when method throws exception

Code Example

@AfterThrowing(
    pointcut = "execution(* com.app.service.*.*(..))",
    throwing = "ex"
)
public void afterError(Exception ex) {
    System.out.println("Exception: " + ex.getMessage());
}

Flow

Client → Proxy → Method → EXCEPTION → @AfterThrowing

Use Cases

  • Error logging
  • Alerting
  • Exception handling

Important Behavior

  • Only runs on failure
  • Can access exception
  • Cannot stop exception

Mental Model

👉 “If something fails, handle it”


5. @Around Advice

👉 Wraps the entire method execution
👉 Gives FULL control

Code Example

@Around("execution(* com.app.service.*.*(..))")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {

    System.out.println("Before execution");

    Object result = joinPoint.proceed(); // actual method call

    System.out.println("After execution");

    return result;
}

Flow

Client → Proxy → @Around (Before) ↓ Actual Method ↓ @Around (After)

Key Power

👉 You can:

  • Run code before
  • Run code after
  • Modify input
  • Modify output
  • Skip execution

Use Cases

  • Performance monitoring
  • Transaction management
  • Retry logic
  • Logging (entry + exit)

Important Behavior

  • Must call joinPoint.proceed()
  • If not → method won’t execute

Mental Model

👉 “I control everything around this method”


Comparison Table

Advice Type When it Runs Access to Result Access to Exception Control
@Before Before method
@After After (always)
@AfterReturning After success
@AfterThrowing After exception
@Around Before + After

Real-World Example (Banking 🏦)

Logging + Performance

@Around("execution(* com.bank.service.*.*(..))")
public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable {

    long start = System.currentTimeMillis();

    Object result = joinPoint.proceed();

    long end = System.currentTimeMillis();

    System.out.println("Execution time: " + (end - start));

    return result;
}

Internal Understanding

👉 All these advices are:

  • Registered in proxy
  • Executed as interceptors
  • Applied before/after method call

What You Must Remember

@Around is most powerful
@Before is simplest
@After always runs
@AfterReturning → success only
@AfterThrowing → failure only


If ALL Advices Are Defined — What Happens?

Suppose you define:

  • @Before
  • @After
  • @AfterReturning
  • @AfterThrowing
  • @Around

Nothing overrides anything
ALL applicable advices will execute\

@Around does NOT replace other advices
👉 It wraps the entire execution

When method executes SUCCESSFULLY:

@Around (before part)
    ↓
@Before
    ↓
Actual Method
    ↓
@AfterReturning
    ↓
@After
    ↓
@Around (after part)

When method throws EXCEPTION:

@Around (before part)
    ↓
@Before
    ↓
Actual Method (throws exception)
    ↓
@AfterThrowing
    ↓
@After
    ↓
@Around (after part)  ← only if handled properly

Let’s See with Code

@Aspect
@Component
class MyAspect {

    @Before("execution(* com.app.service.*.*(..))")
    public void before() {
        System.out.println("Before");
    }

    @After("execution(* com.app.service.*.*(..))")
    public void after() {
        System.out.println("After");
    }

    @AfterReturning("execution(* com.app.service.*.*(..))")
    public void afterReturning() {
        System.out.println("AfterReturning");
    }

    @AfterThrowing("execution(* com.app.service.*.*(..))")
    public void afterThrowing() {
        System.out.println("AfterThrowing");
    }

    @Around("execution(* com.app.service.*.*(..))")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {

        System.out.println("Around Before");

        Object result = pjp.proceed();

        System.out.println("Around After");

        return result;
    }
}

Output (Success Case)

Around Before
Before
[Actual Method]
AfterReturning
After
Around After

Output (Exception Case)

Around Before
Before
[Exception thrown]
AfterThrowing
After
Around After (only if handled)

Note

1. @Around is OUTERMOST

It wraps everything:

@Around {
   @Before
   Method
   @After...
}

2. If @Around DOES NOT call proceed()

pjp.proceed(); // missing ❌

👉 Then:

Method will NOT execute
Other advices will NOT execute\

3. Exception Handling in @Around

try {
    pjp.proceed();
} catch (Exception e) {
    // if handled here
}

👉 Then:

@AfterThrowing may NOT run\

4. @After Always Runs

👉 Like finally block in Java


This site uses Just the Docs, a documentation theme for Jekyll.