@Around advice lets you wrap extra code before and after a method runs. It gives you full control to change inputs, outputs, or handle errors.
@Around advice for full control in Spring Boot
@Around("pointcutExpression") public Object methodName(ProceedingJoinPoint joinPoint) throws Throwable { // code before method Object result = joinPoint.proceed(); // code after method return result; }
The method must return Object and throw Throwable.
Use joinPoint.proceed() to run the original method.
com.example.service package takes to run.@Around("execution(* com.example.service.*.*(..))") public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object proceed = joinPoint.proceed(); long duration = System.currentTimeMillis() - start; System.out.println(joinPoint.getSignature() + " took " + duration + " ms"); return proceed; }
@Around("execution(* com.example.service.UserService.getUser(..))") public Object modifyInput(ProceedingJoinPoint joinPoint) throws Throwable { Object[] args = joinPoint.getArgs(); if(args.length > 0 && args[0] instanceof String) { args[0] = ((String) args[0]).toUpperCase(); } return joinPoint.proceed(args); }
This Spring Boot example uses @Around advice to measure how long any method in the service package takes to run. When the greet method runs, the aspect prints the execution time. The main app calls greet and prints the greeting.
package com.example.demo.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class TimingAspect { @Around("execution(* com.example.demo.service.*.*(..))") public Object measureTime(ProceedingJoinPoint joinPoint) throws Throwable { long start = System.currentTimeMillis(); Object result = joinPoint.proceed(); long end = System.currentTimeMillis(); System.out.println(joinPoint.getSignature() + " executed in " + (end - start) + "ms"); return result; } } // Service class package com.example.demo.service; import org.springframework.stereotype.Service; @Service public class GreetingService { public String greet(String name) { return "Hello, " + name + "!"; } } // Main application to test package com.example.demo; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import com.example.demo.service.GreetingService; @SpringBootApplication public class DemoApplication implements CommandLineRunner { private final GreetingService greetingService; public DemoApplication(GreetingService greetingService) { this.greetingService = greetingService; } public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Override public void run(String... args) throws Exception { String message = greetingService.greet("Alice"); System.out.println(message); } }
Always call joinPoint.proceed() to continue the original method execution.
You can modify arguments by passing a new array to proceed(args).
Use @Around advice carefully as it can change method behavior and affect performance.
@Around advice wraps a method to run code before and after it.
It gives full control to modify inputs, outputs, or handle exceptions.
Remember to call joinPoint.proceed() to run the original method.
Practice
@Around advice in Spring AOP?Solution
Step 1: Understand the role of @Around advice
@Around advice wraps a method, allowing code to run before and after the method execution.Step 2: Compare options with this behavior
Only To run code before and after a method, controlling its execution fully describes full control before and after the method, matching @Around's purpose.Final Answer:
To run code before and after a method, controlling its execution fully -> Option AQuick Check:
@Around advice = full control before and after method [OK]
- Thinking @Around only runs after method
- Confusing @Around with @After or @Before
- Forgetting @Around can modify inputs and outputs
@Around advice method?Solution
Step 1: Recall the method to call original execution
In @Around advice, the original method is executed by calling joinPoint.proceed().Step 2: Match the correct syntax
Only return joinPoint.proceed(); uses the correct method name and syntax to proceed.Final Answer:
return joinPoint.proceed(); -> Option AQuick Check:
Call original method with joinPoint.proceed() [OK]
- Using incorrect method names like execute() or run()
- Forgetting to return the result of proceed()
- Calling proceed() without parentheses
@Around advice code, what will be printed when someMethod() returns "Hello"?
@Around("execution(* someMethod())")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before");
Object result = joinPoint.proceed();
System.out.println("After");
return result + " World";
}Solution
Step 1: Trace the advice execution order
The advice prints "Before", then calls the original method which returns "Hello", then prints "After".Step 2: Understand the returned value
The advice returns the original result plus " World", so the final returned string is "Hello World".Final Answer:
Before After Hello World -> Option DQuick Check:
Prints before and after, returns modified result [OK]
- Assuming original method output is unchanged
- Mixing print order with return value
- Forgetting to add " World" to result
@Around advice method:
@Around("execution(* someMethod())")
public Object aroundAdvice(ProceedingJoinPoint joinPoint) {
System.out.println("Start");
Object result = joinPoint.proceed();
System.out.println("End");
return result;
}Solution
Step 1: Check method signature requirements
joinPoint.proceed() throws Throwable, so the advice method must declare throws Throwable or handle it.Step 2: Identify missing throws declaration
The method lacks "throws Throwable", causing a compile error.Final Answer:
Missing throws Throwable declaration in method signature -> Option BQuick Check:
proceed() throws Throwable, must declare it [OK]
- Ignoring checked exceptions from proceed()
- Using wrong method name instead of proceed()
- Not matching annotation syntax
@Around advice that modifies the input argument of a method before execution and changes the returned result after execution. Which approach correctly achieves this?Solution
Step 1: Understand argument modification in @Around advice
You can get and modify method arguments using joinPoint.getArgs() and pass them to proceed() to change inputs.Step 2: Modify the returned result after proceed()
After calling proceed with modified arguments, you can change the returned value before returning it.Final Answer:
Modify the argument array via joinPoint.getArgs(), then call joinPoint.proceed(modifiedArgs), and finally modify the returned result before returning -> Option CQuick Check:
Change inputs with proceed(args), then modify output [OK]
- Calling proceed() without modified arguments when inputs need change
- Trying to change parameters directly without proceed()
- Ignoring returned result modification
Ready to prove it?
Pass the test and this pattern moves unknown
