Pointcut expressions help you pick specific places in your code to add extra behavior without changing the original code.
Pointcut expressions in Spring Boot
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern? method-name-pattern(param-pattern) throws-pattern?)
The execution keyword is the most common way to write pointcut expressions.
Use * as a wildcard to match any part, like any method name or any return type.
com.example.service package.execution(* com.example.service.*.*(..))
execution(public * *(..))
find in UserRepository class.execution(* com.example.repository.UserRepository.find*(..))
delete that take a single Long parameter and return void in controller package.execution(void com.example.controller.*.delete*(Long))
This example shows a logging aspect that runs before any method in the com.example.service package. When createUser runs, the aspect prints a message first.
package com.example.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.stereotype.Component; @Aspect @Component public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logBefore() { System.out.println("A method in service package is about to run."); } } // Sample service class package com.example.service; import org.springframework.stereotype.Service; @Service public class UserService { public void createUser() { System.out.println("User created."); } } // Main application to run package com.example; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ApplicationContext; import com.example.service.UserService; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { ApplicationContext context = SpringApplication.run(DemoApplication.class, args); UserService userService = context.getBean(UserService.class); userService.createUser(); } }
Pointcut expressions are very flexible and can match many method patterns.
Be careful with wildcards to avoid matching too many methods unintentionally.
Use Spring Boot DevTools or your IDE debugger to test if your pointcuts are working as expected.
Pointcut expressions select where extra code runs without changing original methods.
Use execution() with wildcards to match methods by name, package, or parameters.
They help add logging, security, or other features cleanly and easily.
Practice
Solution
Step 1: Understand the purpose of pointcut expressions
Pointcut expressions specify where additional code, called advice, should be applied in existing methods without changing those methods.Step 2: Differentiate from other concepts
They do not create or replace methods, nor configure databases. Their role is to select join points (methods) for advice.Final Answer:
Select methods where extra code (advice) should run -> Option CQuick Check:
Pointcut expression = Select methods for advice [OK]
- Confusing pointcuts with method creation
- Thinking pointcuts configure databases
- Believing pointcuts replace method code
com.example.service using a pointcut expression?Solution
Step 1: Understand the execution syntax
The syntaxexecution(* com.example.service.*.*(..))matches any return type, any class in the packagecom.example.service, and any method with any parameters.Step 2: Analyze other options
execution(com.example.service.*.*(..)) misses the wildcard for return type. execution(* com.example.service..*(..)) uses double dot..which matches subpackages, not just the package. execution(* com.example.service.*(..)) misses the class wildcard.Final Answer:
execution(* com.example.service.*.*(..)) -> Option DQuick Check:
Use * for any class and method in package [OK]
- Omitting the return type wildcard *
- Using .. instead of * for classes
- Missing method wildcard *
execution(public * com.example.repo.*Repository.find*(..)), which methods will it match?Solution
Step 1: Break down the expression
public *means any public return type,com.example.repo.*Repositorymatches classes ending with 'Repository' in the package, andfind*(..)matches methods starting with 'find' with any parameters.Step 2: Match options to expression meaning
All public methods starting with 'find' in any class ending with 'Repository' in package com.example.repo correctly describes all public methods starting with 'find' in classes ending with 'Repository' in the package. Others are either too broad or too narrow.Final Answer:
All public methods starting with 'find' in any class ending with 'Repository' in package com.example.repo -> Option BQuick Check:
execution(public * com.example.repo.*Repository.find*(..)) = All public methods starting with 'find' in any class ending with 'Repository' in package com.example.repo [OK]
- Ignoring method name prefix 'find*'
- Confusing class name pattern *Repository
- Missing public modifier effect
execution(* com.example..service.*(..)Solution
Step 1: Check syntax completeness
The expression is missing a closing parenthesis ')' at the end, which is required to close the execution() expression.Step 2: Validate other parts
Double dots '..' are valid to match subpackages, '*' is valid for method names, and '*' is valid for return type.Final Answer:
Missing closing parenthesis at the end -> Option AQuick Check:
Check parentheses balance in execution() [OK]
- Forgetting closing parenthesis
- Misunderstanding '..' usage
- Thinking '*' is invalid for methods or return types
com.app.service and its subpackages, but only methods that have exactly two parameters of any type. Which expression is correct?Solution
Step 1: Understand package and subpackage matching
com.app.service..*matches classes in the package and all subpackages.Step 2: Match method parameters exactly
(* , *)means exactly two parameters of any type.(..)means any number of parameters, so it's incorrect here.Step 3: Analyze options
execution(* com.app.service..*.*(*, *)) correctly matches all classes in package and subpackages with exactly two parameters. Others either match any number of parameters or wrong parameter counts.Final Answer:
execution(* com.app.service..*.*(*, *)) -> Option AQuick Check:
Use (*, *) for exactly two parameters [OK]
- Using (..) to match exact parameter count
- Confusing single * with .. for subpackages
- Missing commas between parameters
Ready to prove it?
Pass the test and this pattern moves unknown
