skip to content

JoinPoint vs ProceedingJoinPoint API

JoinPoint exposes args, signature, target and proxy; ProceedingJoinPoint adds proceed() and is only valid inside @Around. Mixing the two up is a common mistake, which is why it gets asked.

part ofSpring Frameworkoverview, primer and where to startread it →
on this pageshow

questions

5

What is a JoinPoint in Spring AOP advice, and what information does it expose?

level: juniorimportance: must knowfreq 70%

answer

  1. First param of advice
  2. getArgs / getSignature / getTarget / getThis
  3. cast Signature to MethodSignature
  4. target = real bean, this = proxy
  5. read-only inspection

basics

~10 s

JoinPoint is an object Spring passes to advice methods representing the intercepted method call. It exposes getArgs() (the call's arguments), getSignature() (method name/details), getTarget() (the real bean), and getThis() (the proxy).

solid answer

~30 s

A JoinPoint is the runtime handle Spring AOP passes into advice (@Before, @After, @AfterReturning, @AfterThrowing) describing the method invocation being advised. If you declare it, it must be the first parameter. Its main methods are: getArgs() returns Object[] of the actual arguments; getSignature() returns a Signature you usually cast to MethodSignature to read the method name, return type, and parameter names; getTarget() returns the underlying target bean; getThis() returns the AOP proxy wrapping it. You use it for cross-cutting concerns like logging or auditing where you need to inspect what method ran and with which arguments, without changing the business code.

code

java · 19 lines
java
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {

    @Before("execution(* com.katajob.service..*(..))")
    public void logCall(JoinPoint jp) {           // JoinPoint must be first param
        MethodSignature sig = (MethodSignature) jp.getSignature();
        System.out.println("Calling " + sig.getDeclaringTypeName()
                + "." + sig.getName()
                + " args=" + java.util.Arrays.toString(jp.getArgs())
                + " targetClass=" + jp.getTarget().getClass().getSimpleName());
    }
}

go deeper

for a junior

Know it's the first advice parameter and the four getters and what each returns.

for a middle

Explain casting to MethodSignature and that getArgs() is read-only for inspection.

for a senior

Contrast target vs this precisely and note the copy-array gotcha.

for a principal

Frame JoinPoint as the inspection surface vs ProceedingJoinPoint as the control surface, and discuss proxy internals.

**AOP terms first.** In Aspect-Oriented Programming, a *join point* is a point in program execution where an aspect can be applied — in Spring AOP this is always a *method execution* on a Spring bean. *Advice* is the code that runs at that join point (e.g. `@Before`, `@AfterReturning`). A *pointcut* selects which join points get advised. Spring implements this with a *proxy*: it wraps your bean in a generated object (JDK dynamic proxy or CGLIB subclass) that runs the advice around the real method. **The `org.aspectj.lang.JoinPoint` object.** When advice runs, Spring can hand it a `JoinPoint` describing the intercepted call. To receive it, declare it as the **first parameter** of the advice method. It is available in all advice kinds (`@Before`, `@After`, `@AfterReturning`, `@AfterThrowing`, and `@Around` — where the richer subtype `ProceedingJoinPoint` is used instead). **Its four core methods:** - **`Object[] getArgs()`** — the arguments passed to the intercepted method, in declared order. Returns an array you can read for logging/validation. Note: it is effectively a snapshot; mutating this array does **not** change the arguments the method actually receives (only `ProceedingJoinPoint.proceed(args)` can do that). - **`Signature getSignature()`** — metadata about the member being called. It is a generic `Signature`; for method execution you cast to `org.aspectj.lang.reflect.MethodSignature` to reach `getMethod()`, `getReturnType()`, `getParameterTypes()`, `getParameterNames()`. `getSignature().getName()` gives the method name and `getSignature().getDeclaringTypeName()` the class. - **`Object getTarget()`** — the **target** object: your real, un-proxied bean instance. - **`Object getThis()`** — the **proxy** object that Spring created around the target. For a CGLIB proxy this is the generated subclass; for a JDK proxy it is the interface-implementing proxy. **Other members** (out of scope but real): `getKind()`, `getSourceLocation()`, `getStaticPart()`, and `toString()/toShortString()/toLongString()`. **When to use it.** Logging/tracing, auditing, metrics, and diagnostics — any concern that needs to know *what* is running and *with what inputs* without altering behavior. If you also need to control or replace the invocation (skip it, retry it, change args, transform the return value), you need `@Around` with `ProceedingJoinPoint`. **Gotchas.** (1) The `JoinPoint` parameter must come first, before any pointcut-bound parameters. (2) `getSignature()` returns `Signature`, not `MethodSignature` — cast it. (3) `getArgs()` gives a copy-like array; editing it is not a way to change the real call.

  • Which advice types can receive a JoinPoint?
    All of them — @Before, @After, @AfterReturning, @AfterThrowing, and @Around (there it is the ProceedingJoinPoint subtype). It must be the first parameter if declared.
  • Why cast getSignature() to MethodSignature?
    getSignature() returns the generic Signature interface. MethodSignature adds method-specific accessors like getMethod(), getReturnType(), and getParameterNames() that Signature doesn't expose.

saying these in an interview costs you the question

  • Saying getArgs() lets you mutate the real arguments
  • Thinking JoinPoint can call the target method (that's proceed() on ProceedingJoinPoint)
  • Confusing getTarget() and getThis()
  • Claiming JoinPoint only works in @Around

context

open as a page

How does ProceedingJoinPoint differ from JoinPoint, and where can you use it?

level: middleimportance: must knowfreq 75%

basics

~20 s

ProceedingJoinPoint extends JoinPoint and adds proceed(), which actually invokes the advised method (or the next advice in the chain). It is valid only inside @Around advice. Other advice types get the plain JoinPoint, which cannot proceed.

open as a page

How do you modify method arguments from an @Around advice, and why doesn't editing getArgs() work?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Call proceed(Object[] args) with a new argument array — that array is what the target actually receives. Editing the array from getArgs() alone does not change the real call; you must pass your modified array into proceed(args).

open as a page

What is the difference between JoinPoint.getTarget() and JoinPoint.getThis()?

level: seniorimportance: should knowfreq 45%

basics

~20 s

getTarget() returns the real, un-proxied bean instance. getThis() returns the AOP proxy Spring created around it. They're usually different objects; the proxy is what other beans actually call, and the target holds your business logic.

open as a page

Explain the semantics of proceed() in the interceptor chain: what it invokes, multiple/zero calls, and the return-value and exception contract.

level: principalimportance: should knowfreq 35%

basics

~20 s

proceed() advances the AOP interceptor chain to the next advice, and eventually the target method. Not calling it skips the target; calling it multiple times re-invokes the chain (retry). It returns the downstream result and propagates any Throwable, so you must return its value.

open as a page