skip to content

What is a named pointcut in Spring AOP, and how do you declare one with @Pointcut?

level: juniorimportance: must knowfreq 60%

answer

  1. empty void method
  2. method name = pointcut name
  3. @Pointcut(expr) then @Before(name())
  4. body never runs
  5. DRY reuse of expression

basics

~10 s

A named pointcut gives a pointcut expression a name so you can reuse it. You declare it by annotating an empty, void-returning method with @Pointcut("...expression..."); the method name becomes the pointcut's name.

solid answer

~40 s

In Spring AOP a pointcut is a predicate that selects join points (in Spring, method executions) where advice runs. Instead of repeating the same raw expression string in every advice annotation, @Pointcut lets you name it once. You put @Pointcut("execution(* com.app.service.*.*(..))") on an empty method with a void return type — the method body is never executed and just carries the signature. The method name (plus any parameters) becomes the pointcut identifier, and advice annotations reference it by calling that name, e.g. @Before("serviceMethods()"). This is the DRY, readable way to write pointcuts: one definition, many references, and a change in one place updates everywhere.

code

java · 18 lines
java
@Aspect
@Component
public class LoggingAspect {

    // Named pointcut: void, empty body, name = identifier
    @Pointcut("execution(* com.app.service.*.*(..))")
    void serviceMethods() {}

    @Before("serviceMethods()")           // reference by name
    public void logEntry(JoinPoint jp) {
        System.out.println("-> " + jp.getSignature().toShortString());
    }

    @AfterReturning("serviceMethods()")   // reuse the same pointcut
    public void logExit(JoinPoint jp) {
        System.out.println("<- " + jp.getSignature().toShortString());
    }
}

go deeper

for a junior

Know it's @Pointcut on an empty void method, name = identifier, referenced from advice by name.

for a middle

Explain the DRY/readability benefit and that parameters/visibility matter.

for a senior

Contrast with inline strings, mention AspectJ expression language and IDE navigability.

for a principal

Frame as the unit of a shared, governed pointcut vocabulary across a codebase.

**Vocabulary first.** In Aspect-Oriented Programming (AOP), a *join point* is a point during execution where you could insert behavior; in Spring AOP the only join points are *method executions* on Spring beans. A *pointcut* is a predicate/expression that *selects* which join points match. *Advice* is the code that runs at a matched join point (e.g. @Before, @After, @Around). **The problem @Pointcut solves.** You can write the pointcut expression inline in the advice annotation: `@Before("execution(* com.app.service.*.*(..))")`. But if ten advices need the same selection, you copy that string ten times — error-prone and unreadable. A *named pointcut* names the expression once so it can be reused. **How to declare one.** Annotate a method with `@Pointcut(value)` where `value` is the pointcut expression. Rules: - The method **must return void**. - The method body is **empty** — it is never actually invoked; only its signature matters. - The **method name becomes the pointcut's name** (the identifier you reference from advice). - The method's **parameters** form the pointcut's parameters (used when you need to bind arguments, e.g. via `args()`). - The method's **access modifier** controls visibility: `private` restricts references to the same aspect class; `public`/`protected`/package-private widen who can reference it. ```java @Aspect @Component public class LoggingAspect { @Pointcut("execution(* com.app.service.*.*(..))") void serviceMethods() {} // named pointcut, no body @Before("serviceMethods()") // reference by name public void logEntry(JoinPoint jp) { System.out.println("Entering " + jp.getSignature()); } } ``` **Why this works.** Spring uses the AspectJ pointcut language and weaving model for expression parsing (even though runtime weaving is proxy-based). When it processes `@Before("serviceMethods()")`, it resolves the reference to the `@Pointcut`-annotated method's expression. Referencing looks like a method call syntactically (`serviceMethods()`), but no Java method is ever called — it's a name lookup in the pointcut namespace. **Gotchas / edge cases.** - Returning non-void from the `@Pointcut` method is invalid and will fail. - Don't put logic in the body — it's dead code and never runs. - The `()` after the name in an advice string are part of pointcut-reference syntax, not a Java call. - Named pointcuts are scoped like Java methods, so IDEs can navigate/rename them — a big readability win over string literals. **When to use.** Any time an expression is used more than once, is complex enough to deserve a name, or you want a single source of truth for 'what counts as a service method' etc.

  • Why must the @Pointcut method return void and have an empty body?
    Because it is only a carrier for a signature and expression, not real logic. Spring/AspectJ never invokes it; it reads the method name (the pointcut identifier), its parameters (pointcut parameters), and the annotation's expression. A non-void return is rejected, and any body would be dead code.
  • How is referencing a named pointcut different from an inline expression?
    An inline expression is a raw string duplicated at each advice; a named reference (serviceMethods()) points to a single @Pointcut definition, so it's DRY, IDE-navigable/renamable, and changing the expression once updates every advice that references it.

saying these in an interview costs you the question

  • Thinking the @Pointcut method body actually executes
  • Making it return boolean/other type instead of void
  • Believing serviceMethods() in the advice string is a real Java method call

context