📖 Scenario: You are building a Spring Boot application and want to measure how long certain methods take to run. This helps you find slow parts and improve your app's speed.
🎯 Goal: Create an Aspect using Spring AOP that logs the execution time of a method called processData in a service class.
📋 What You'll Learn
Create a service class called DataService with a method processData that simulates work by sleeping for 500 milliseconds.
Create an Aspect class called PerformanceAspect that uses @Around advice to measure execution time of processData.
Log the execution time in milliseconds with a message like: Execution time of processData: X ms.
Call the processData method from the main application and see the logged output.
💡 Why This Matters
🌍 Real World
Performance monitoring is critical in real applications to find slow parts and optimize them. Using AOP lets you add this monitoring without changing business logic code.
💼 Career
Many companies use Spring Boot and AOP for cross-cutting concerns like logging and performance. Knowing this helps you build maintainable and efficient applications.
Progress0 / 4 steps
1
Create the DataService class with processData method
Create a class called DataService with a public method processData that sleeps for 500 milliseconds using Thread.sleep(500). The method should not return anything.
Spring Boot
Hint
Use @Service annotation on the class. Inside processData, use Thread.sleep(500) inside a try-catch block.
2
Create PerformanceAspect with @Around advice
Create a class called PerformanceAspect annotated with @Aspect and @Component. Define an @Around advice method called measureExecutionTime that targets the execution of processData method in DataService. The advice should record start and end time using System.currentTimeMillis().
Spring Boot
Hint
Use @Around advice with a pointcut expression targeting processData. Use ProceedingJoinPoint to proceed with method execution.
3
Call processData method from main application
In the main Spring Boot application class, autowire DataService and call the processData method inside the run method of CommandLineRunner.
Spring Boot
Hint
Implement CommandLineRunner in the main class. Autowire DataService and call processData() inside run.
4
Run the application and verify output
Run the Spring Boot application. Check the console output for the line starting with Execution time of processData: showing the time in milliseconds.
Spring Boot
Hint
Look for console output starting with Execution time of processData:. The number will be around 500 ms.
Practice
(1/5)
1. What is the main purpose of using AOP for performance monitoring in Spring Boot?
easy
A. To measure method execution time without changing the method code
B. To change the business logic of methods
C. To add new REST endpoints automatically
D. To replace database queries with cached results
Solution
Step 1: Understand AOP's role in performance monitoring
AOP allows adding extra code around methods without modifying their original code.
Step 2: Identify the purpose of timing code
Timing code measures how long methods take to run, helping find slow parts.
Final Answer:
To measure method execution time without changing the method code -> Option A
Quick Check:
AOP measures time without code changes [OK]
Hint: AOP adds timing code outside main methods [OK]
Common Mistakes:
Thinking AOP changes method logic
Confusing AOP with adding endpoints
Assuming AOP caches database queries
2. Which annotation is used in Spring AOP to wrap method execution for timing?
Step 2: Identify which advice can measure execution time
@Around can run code before and after method, so it can measure duration.
Final Answer:
@Around -> Option C
Quick Check:
@Around wraps method for timing [OK]
Hint: Use @Around to wrap and time methods [OK]
Common Mistakes:
Using @Before or @After which can't measure duration
Confusing @Pointcut with advice annotation
Assuming @After runs before method
3. Given this AOP method, what will be printed if the target method takes 150ms to execute?
@Around("execution(* com.example.service.*.*(..))")
public Object measureTime(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
Object result = pjp.proceed();
long end = System.currentTimeMillis();
System.out.println("Execution time: " + (end - start) + " ms");
return result;
}
medium
A. Execution time: 0 ms
B. No output printed
C. Execution time: 300 ms
D. Execution time: 150 ms
Solution
Step 1: Understand timing calculation
The code records start time, runs the method, then records end time and prints the difference.
Step 2: Match timing with method duration
If method takes 150ms, printed time is 150 ms.
Final Answer:
Execution time: 150 ms -> Option D
Quick Check:
Printed time matches method duration [OK]
Hint: Printed time equals method run duration [OK]
Common Mistakes:
Assuming time is zero or double counted
Thinking no output prints
Confusing start and end time order
4. What is wrong with this AOP advice for measuring execution time?
@Around("execution(* com.example..*(..))")
public void measure(ProceedingJoinPoint pjp) throws Throwable {
long start = System.currentTimeMillis();
pjp.proceed();
long end = System.currentTimeMillis();
System.out.println("Time: " + (end - start));
}
medium
A. The pointcut expression is invalid
B. The method should return Object, not void
C. System.currentTimeMillis() cannot be used for timing
D. ProceedingJoinPoint cannot be used in @Around advice
Solution
Step 1: Check method signature for @Around advice
@Around advice must return the result of pjp.proceed() to maintain method behavior.
Step 2: Identify missing return statement
Method returns void but should return Object from pjp.proceed().
Final Answer:
The method should return Object, not void -> Option B
Quick Check:
@Around advice must return method result [OK]
Hint: @Around methods must return Object from proceed() [OK]
Common Mistakes:
Forgetting to return pjp.proceed() result
Thinking pointcut syntax is wrong
Believing System.currentTimeMillis() is invalid
5. You want to monitor execution time of all service methods but exclude methods annotated with @SkipTiming. Which AOP pointcut expression correctly achieves this?
hard
A. execution(* com.example.service..*(..)) && !@annotation(com.example.SkipTiming)
B. execution(* com.example.service..*(..)) || @annotation(com.example.SkipTiming)
C. execution(* com.example.service..*(..)) && @annotation(com.example.SkipTiming)
D. !execution(* com.example.service..*(..)) && !@annotation(com.example.SkipTiming)
Solution
Step 1: Understand pointcut logic for inclusion and exclusion
We want all service methods except those with @SkipTiming annotation.
Step 2: Use && with negation to exclude annotated methods
Use 'execution(...) && !@annotation(...)' to include methods but exclude those annotated.
Final Answer:
execution(* com.example.service..*(..)) && !@annotation(com.example.SkipTiming) -> Option A
Quick Check:
Exclude annotated methods with !@annotation [OK]
Hint: Use && !@annotation to exclude methods [OK]
Common Mistakes:
Using || which includes annotated methods
Using && @annotation which includes only annotated
Negating execution pointcut incorrectly
Recommended
Ready to prove it?
Pass the test and this pattern moves unknownstrongwhile earning +1 Grip toward your certificate.