Bird
Raised Fist0
Spring Bootframework~10 mins

AOP for performance monitoring in Spring Boot - Step-by-Step Execution

Choose your learning style10 modes available
Concept Flow - AOP for performance monitoring
Method call intercepted
↓
Start timer
↓
Proceed with method execution
↓
Stop timer
↓
Calculate duration
↓
Log or record performance
↓
Return method result
This flow shows how AOP intercepts a method call to measure and log its execution time for performance monitoring.
Execution Sample
Spring Boot
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;

@Aspect
public class PerformanceAspect {
  @Around("execution(* com.example..*(..))")
  public Object monitor(ProceedingJoinPoint pjp) throws Throwable {
    long start = System.currentTimeMillis();
    Object result = pjp.proceed();
    long duration = System.currentTimeMillis() - start;
    System.out.println(pjp.getSignature() + " executed in " + duration + " ms");
    return result;
  }
}
This code intercepts method calls in com.example package, measures execution time, logs it, and returns the original result.
Execution Table
StepActionEvaluationResult
1Intercept method callMethod: exampleMethod()Proceed to timing
2Start timerSystem.currentTimeMillis()start = 1680000000000
3Execute original methodexampleMethod() runsMethod returns 'Success'
4Stop timerSystem.currentTimeMillis()end = 1680000000123
5Calculate durationend - startduration = 123 ms
6Log performancePrint signature and durationOutput: exampleMethod() executed in 123 ms
7Return resultReturn 'Success' to callerCaller receives 'Success'
💡 Method execution completed and performance logged
Variable Tracker
VariableStartAfter Step 2After Step 4After Step 5Final
startnull1680000000000168000000000016800000000001680000000000
endnullnull168000000012316800000001231680000000123
durationnullnullnull123123
resultnullnull'Success''Success''Success'
Key Moments - 3 Insights
Why do we call pjp.proceed() inside the around advice?
Calling pjp.proceed() executes the original method. Without it, the method would not run, so no result or timing would be possible. See execution_table step 3.
Why do we measure time before and after pjp.proceed()?
Measuring before and after lets us calculate how long the method took to run. This is the core of performance monitoring. See execution_table steps 2 and 4.
What happens if the original method throws an exception?
The exception will propagate unless caught. The timing stops at pjp.proceed(), so duration may not be logged if exception occurs. This is important to handle in real code.
Visual Quiz - 3 Questions
Test your understanding
Look at the execution table, what is the value of 'duration' after step 5?
Anull
B1680000000123
C123 ms
D1680000000000
💡 Hint
Check the 'duration' variable in variable_tracker after step 5
At which step does the original method actually run?
AStep 2
BStep 3
CStep 5
DStep 6
💡 Hint
Look at the 'Action' column in execution_table for method execution
If pjp.proceed() was not called, what would happen to the 'result' variable?
AIt would be null
BIt would hold the method's return value
CIt would cause a compile error
DIt would be set to duration
💡 Hint
See variable_tracker 'result' variable initialization and update
Concept Snapshot
AOP for performance monitoring uses an around advice to intercept method calls.
It records start time, executes the method, records end time, and calculates duration.
The duration is logged for performance insights.
Always call pjp.proceed() to run the original method.
Handle exceptions to ensure timing is accurate.
This helps track slow methods without changing their code.
Full Transcript
Aspect-Oriented Programming (AOP) for performance monitoring intercepts method calls to measure how long they take to execute. The around advice starts a timer before running the method, then stops the timer after the method finishes. It calculates the duration and logs it. The original method is executed by calling pjp.proceed(). Variables like start time, end time, duration, and result track the process. This technique helps developers find slow parts of their application without modifying the original code directly.

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

  1. Step 1: Understand AOP's role in performance monitoring

    AOP allows adding extra code around methods without modifying their original code.
  2. Step 2: Identify the purpose of timing code

    Timing code measures how long methods take to run, helping find slow parts.
  3. Final Answer:

    To measure method execution time without changing the method code -> Option A
  4. 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?
easy
A. @Before
B. @After
C. @Around
D. @Pointcut

Solution

  1. Step 1: Recall Spring AOP advice types

    @Before runs before method, @After runs after, @Around wraps method execution.
  2. Step 2: Identify which advice can measure execution time

    @Around can run code before and after method, so it can measure duration.
  3. Final Answer:

    @Around -> Option C
  4. 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

  1. Step 1: Understand timing calculation

    The code records start time, runs the method, then records end time and prints the difference.
  2. Step 2: Match timing with method duration

    If method takes 150ms, printed time is 150 ms.
  3. Final Answer:

    Execution time: 150 ms -> Option D
  4. 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

  1. Step 1: Check method signature for @Around advice

    @Around advice must return the result of pjp.proceed() to maintain method behavior.
  2. Step 2: Identify missing return statement

    Method returns void but should return Object from pjp.proceed().
  3. Final Answer:

    The method should return Object, not void -> Option B
  4. 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

  1. Step 1: Understand pointcut logic for inclusion and exclusion

    We want all service methods except those with @SkipTiming annotation.
  2. Step 2: Use && with negation to exclude annotated methods

    Use 'execution(...) && !@annotation(...)' to include methods but exclude those annotated.
  3. Final Answer:

    execution(* com.example.service..*(..)) && !@annotation(com.example.SkipTiming) -> Option A
  4. 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 unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard