Learnitweb

Counting Method Invocations Using @Before Advice with Spring AOP and Micrometer

In this tutorial, you’ll learn how to use Spring AOP with Micrometer to:

  • Count how many times a specific method is invoked.
  • Use the @Before advice to increment a counter before method execution.
  • Keep controller code clean by not adding metrics code inside it.

Prerequisites

Make sure your Spring Boot project includes these dependencies:

<!-- AspectJ for AOP support -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

<!-- Actuator for Micrometer integration -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

You should also have a controller method that you want to observe. For this example, we’ll use a method called fetchQuestions() in QuizController.

Step 1: Create or Update the Aspect Class

If you have already created an aspect (like QuizAspect), you can extend it. Otherwise, create one in the aspects package.

Updated QuizAspect Class

package com.example.demo.aspects;

import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class QuizAspect {

    private final Counter quizCounter;

    public QuizAspect(MeterRegistry meterRegistry) {
        this.quizCounter = Counter.builder("quiz.counter")
            .tag("source", "quizSummary")
            .description("Counts how many times fetchQuestions() is called")
            .register(meterRegistry);
    }

    @Before("execution(public * com.example.demo.controllers.QuizController.fetchQuestions(..))")
    public void countFetchQuestionsCall() {
        quizCounter.increment();
    }
}

Explanation

  • @Aspect: Declares this class as an AOP Aspect.
  • @Before(...): This advice runs before the matched method (fetchQuestions) is executed.
  • Counter: A Micrometer metric that increases only (used for counts, not durations).
  • quizCounter.increment(): Increments the counter each time the method is called.
  • MeterRegistry: Micrometer’s central registry for all metrics.

Step 2: Ensure You Have a Controller Method to Count

Example controller:

package com.example.demo.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class QuizController {

    @GetMapping("/fetch-questions")
    public String fetchQuestions() {
        return "Returning quiz questions...";
    }
}

Step 3: Enable AOP in the Application

Make sure your main class has this annotation:

@EnableAspectJAutoProxy
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

Step 4: Run the Application and Call the Endpoint

Call the endpoint /fetch-questions a few times via browser, curl, or Postman:

curl http://localhost:8080/fetch-questions

Try this 7 times (for example).

Step 5: View the Metrics

Visit:

http://localhost:8080/actuator/metrics/quiz.counter

You should see a JSON output like:

{
  "name": "quiz.counter",
  "measurements": [
    {
      "statistic": "count",
      "value": 7.0
    }
  ],
  "availableTags": [
    {
      "tag": "source",
      "values": ["quizSummary"]
    }
  ]
}

To filter by the source tag:

http://localhost:8080/actuator/metrics/quiz.counter?tag=source:quizSummary