What is @AfterThrowing advice in Spring AOP and when does it run?
answer
- Runs only on exceptional exit
- Observe-only, doesn't swallow
- Proxy-based, one of 5 advice types
- @AfterReturning = normal, @After = finally
basics
~10 s@AfterThrowing is an aspect advice method that runs only when the matched method (join point) exits by throwing an exception. If the method returns normally, it does not run.
solid answer
~40 s@AfterThrowing is one of Spring AOP's advice types (alongside @Before, @After, @AfterReturning, and @Around). You annotate a method in an @Aspect class with @AfterThrowing and a pointcut. Spring wraps the target bean in a proxy; when a matched method is invoked and throws an exception, the proxy invokes your advice AFTER the exception is thrown but before it propagates to the caller. It runs only on the exceptional exit path — never when the method returns normally. Crucially, @AfterThrowing observes the exception; it does not stop propagation, so the original exception still reaches the caller. Typical uses are cross-cutting logging, metrics, or alerting on failures. Because it relies on a proxy, it only intercepts calls that go through the Spring-managed bean, not internal self-invocations.
code
java · 10 lines@Aspect
@Component
public class FailureLoggingAspect {
private static final Logger log = LoggerFactory.getLogger(FailureLoggingAspect.class);
@AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex")
public void logFailure(JoinPoint jp, Throwable ex) {
log.warn("{} threw {}", jp.getSignature().toShortString(), ex.toString());
}
}go deeper
Must know it runs only when the method throws, and that it's proxy-based.
Should contrast with @AfterReturning/@After and know it doesn't swallow.
Should discuss proxy self-invocation and observe-only semantics.
Frames it as failure observability vs @Around for recovery, plus ordering.
### What it is `@AfterThrowing` is an **advice type** in Spring AOP (Aspect-Oriented Programming). AOP lets you factor out *cross-cutting concerns* — logic like logging, security, or metrics that would otherwise be scattered across many methods — into a single reusable unit called an **aspect**. Key vocabulary: - **Aspect**: a class annotated with `@Aspect` (and usually `@Component` so Spring manages it) that holds advice. - **Join point**: a point in program execution where an aspect can act. In Spring AOP this is always a **method execution** on a Spring bean. - **Pointcut**: an expression selecting which join points to advise, e.g. `execution(* com.example.service.*.*(..))`. - **Advice**: the code that runs at a join point. `@AfterThrowing` is *after-throwing advice*. ### When it runs `@AfterThrowing` advice runs **only when the matched method exits by throwing an exception** (a Throwable propagating out). If the method returns normally, the advice does not run — that is what `@AfterReturning` is for. `@After` (the *finally* advice) runs on both paths. ### How Spring makes it work Spring AOP is **proxy-based**. When a bean is advised, Spring creates a proxy (a JDK dynamic proxy if the bean implements an interface, otherwise a CGLIB subclass proxy). Callers get the proxy. On each call the proxy runs an interceptor chain; if the underlying target method throws, the after-throwing interceptor calls your advice, then the exception continues to propagate. ### Minimal example ```java @Aspect @Component public class FailureLoggingAspect { private static final Logger log = LoggerFactory.getLogger(FailureLoggingAspect.class); @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))", throwing = "ex") public void logFailure(JoinPoint jp, Throwable ex) { log.warn("{} failed: {}", jp.getSignature().toShortString(), ex.getMessage()); } } ``` ### Important properties - **It does not swallow the exception.** The original exception still reaches the caller. `@AfterThrowing` cannot suppress, replace, or recover from it — only observe it. To do that you need `@Around`. - **It cannot change the return value** (there is no normal return on this path). - **Proxy limitation**: only calls that pass through the proxy are intercepted. A method calling another method on `this` (self-invocation) bypasses the proxy, so the advice won't fire for the inner call. ### When to use Use `@AfterThrowing` for observe-only failure handling: logging exceptions, incrementing error counters/metrics, emitting alerts, auditing. When you need to *handle* the exception (translate, retry, return a fallback), use `@Around` instead.
- Does @AfterThrowing stop the exception from reaching the caller?No. It only observes the exception; the original exception continues to propagate. To suppress or replace it you must use @Around and either not rethrow or throw a different exception.
- Which advice runs when a method returns normally instead of throwing?@AfterReturning runs on normal return; @After (finally-style) runs on both normal and exceptional exit; @AfterThrowing runs only on the exceptional path.