skip to content

@Pointcut: Reusable Named Pointcuts

@Pointcut on an empty method gives an expression a name you can reuse and combine with && || !, even across aspects. A small thing interviewers use to tell whether you have written aspects or only read about them.

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

questions

5

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

open as a page

How do you compose named pointcuts using &&, || and !?

level: middleimportance: should knowfreq 45%

basics

~10 s

Combine named pointcuts inside another @Pointcut (or advice) expression with && (both match), || (either matches) and ! (negation). Example: @Pointcut("serviceMethods() && !readOnlyMethods()").

open as a page

How do you reference a named pointcut declared in a DIFFERENT aspect class, and what role does the pointcut method's visibility play?

level: seniorimportance: should knowfreq 40%

basics

~20 s

Use the fully-qualified reference: ClassName.pointcutName() (or the full package path). The pointcut method must be visible enough — make it public (or protected/package-private) so other aspects can reference it; a private @Pointcut is only usable inside its own class.

open as a page

Can a named @Pointcut declare parameters, and how are they used to bind values into advice?

level: seniorimportance: nice to knowfreq 25%

basics

~20 s

Yes. The @Pointcut method's parameters become the pointcut's parameters. Binding designators like args(), this(), target() and @annotation() tie a matched value to a named parameter, and advice with the same parameter names receives that value.

open as a page

How would you organize named pointcuts across a large codebase, and what maintainability and matching pitfalls do you watch for?

level: principalimportance: nice to knowfreq 20%

basics

~20 s

Centralize shared selections in one or a few public @Pointcut declaration classes (a CommonPointcuts library), give each an intent-revealing name, compose smaller pointcuts into bigger ones, and keep raw designators out of advice. Watch package-based expressions that silently stop matching after refactors.

open as a page