1. Manually use StopWatch
The most direct way is to use the one provided by SpringStopWatch
Class, this method is simple and intuitive, suitable for temporary performance testing.
import ; @Service public class UserService { public User findUserById(Long id) { StopWatch stopWatch = new StopWatch(); (); // Business logic User user = (id).orElse(null); (); ("findUserById method takes time:" + () + "ms"); return user; } }
Advantages: Simple and intuitive, no additional configuration required
Disadvantages: Intrusion into business code, not elegant enough, needs to be manually added to each method that needs to be monitored
2. Use AOP to implement time-consuming statistics on global methods
AOP (sectional-oriented programming) is an ideal choice for implementing time-consuming statistics of methods. It can uniformly process time-consuming statistics without modifying the original code.
First, add AOP dependencies:
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
Then, create the facet class:
import ; import ; import ; import ; import ; import ; @Aspect @Component public class MethodTimeAspect { @Pointcut("execution(* .*.*(..))") public void serviceMethodPointcut() {} @Around("serviceMethodPointcut()") public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable { StopWatch stopWatch = new StopWatch(); (); // Execute the target method Object result = (); (); String methodName = ().getName(); ("method[" + methodName + "]time consuming:" + () + "ms"); return result; } }
Advantages: Non-invasive code, unified management, flexible configuration
Disadvantages: Inadequate customization requirements for specific methods
3. Custom annotations + AOP to achieve more refined control
This method combines custom annotations and AOP to more precisely control which methods require time-consuming statistics.
First, create a custom annotation:
import .*; @Target() @Retention() @Documented public @interface TimeLog { String value() default ""; }
Then, create a section class to process methods with this annotation:
import ; import ; import ; import ; import ; import ; @Aspect @Component public class TimeLogAspect { @Around("@annotation()") public Object timeLogAround(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) (); TimeLog timeLog = ().getAnnotation(); String methodDesc = ().isEmpty() ? ().getName() : (); StopWatch stopWatch = new StopWatch(); (); Object result = (); (); ("method[" + methodDesc + "]time consuming:" + () + "ms"); return result; } }
Example of usage:
@Service public class ProductService { @TimeLog("Query product details") public Product getProductDetail(Long id) { // Business logic return (id).orElse(null); } }
Advantages: More fine control, annotations can carry more information, making it easier to customize
Disadvantages: Need to manually add annotations to the method
4. Use interceptor to count the time spent on Controller interface
If you only focus on the time-consuming interface of the Controller layer, you can use Spring's interceptor:
import ; import ; import ; import ; import ; @Component public class ApiTimeInterceptor implements HandlerInterceptor { private ThreadLocal<Long> startTime = new ThreadLocal<>(); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { (()); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { long endTime = (); long executionTime = endTime - (); String uri = (); ("interface[" + uri + "]time consuming:" + executionTime + "ms"); (); } }
Register the interceptor:
import ; import ; import ; @Configuration public class WebConfig implements WebMvcConfigurer { private final ApiTimeInterceptor apiTimeInterceptor; public WebConfig(ApiTimeInterceptor apiTimeInterceptor) { = apiTimeInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { (apiTimeInterceptor).addPathPatterns("/api/"); } }
Advantages: Focus on the performance of the Web interface and perform unified monitoring of the interface
Disadvantages: Only the Controller layer method can be monitored, but the internal service method cannot be monitored.
5. Use Actuator + Micrometer to achieve fine-grained monitoring
Spring Boot Actuator provides integration with Micrometer to enable more professional performance metrics collection:
Add dependencies:
<dependency> <groupId></groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId></groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency>
Method timing using Micrometer:
import ; import ; import ; @Service public class OrderService { private final MeterRegistry meterRegistry; public OrderService(MeterRegistry meterRegistry) { = meterRegistry; } public Order createOrder(OrderRequest request) { sample = (meterRegistry); // Business logic Order order = processOrder(request); (("")); return order; } }
Configure Actuator exposure metrics:
management: endpoints: web: exposure: include: metrics,prometheus metrics: export: prometheus: enabled: true
Advantages: Professional performance indicator collection, can be integrated with monitoring systems such as Prometheus and Grafana, suitable for production environments
Disadvantages: The configuration is relatively complex and has certain learning costs
6. Use Filter to implement request time-consuming statistics
Create a Filter implementation class that can record the start and end time of each HTTP request, thereby calculating the overall time-consuming of the request.
import ; import ; import ; import ; import ; import ; import ; @Component public class TimingFilter implements Filter { @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { long startTime = (); // Continue to process the request (request, response); long endTime = (); long executionTime = endTime - startTime; String requestUri = ((HttpServletRequest) request).getRequestURI(); ("ask[" + requestUri + "]time consuming:" + executionTime + "ms"); } @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void destroy() {} }
advantage: The time-consuming process of all web requests can be monitored globally.
shortcoming: Only provide the time-consuming process of the overall request, and cannot penetrate into the execution time of the specific business logic.
7. Use ServletRequestHandledEvent to count the time spent in request processing
Spring Boot providesServletRequestHandledEvent
Events can be used to monitor the processing time of HTTP requests. This method is suitable for global monitoring of all requests.
First, create an event listener:
import ; import ; import ; @Component public class RequestTimingListener implements ApplicationListener<ServletRequestHandledEvent> { @Override public void onApplicationEvent(ServletRequestHandledEvent event) { ("ask[" + () + "]time consuming:" + () + "ms"); } }
This method automatically listens to the processing results and does not require explicit time-consuming statistics in each controller.
Advantages: No need to modify existing code, monitoring the time-consuming of global requests
Disadvantages: Granular control of custom requests is not supported
Summary and comparison
In SpringBoot, the above seven methods have their own advantages and disadvantages, and you can choose the appropriate solution according to different scenarios:
- StopWatch manual statistics: suitable for temporary testing, fast implementation
- Global AOP: Suitable for performance monitoring of the entire service layer
- Custom annotations + AOP: Suitable for refined control, only monitoring key methods
- Interceptor: suitable for web interface monitoring
- Actuator+Micrometer: Suitable for production environments, integrated with professional monitoring systems
- Filter: suitable for global request monitoring, lightweight implementation
- ServletRequestHandledEvent: Globally monitor HTTP request processing time, no code changes are required
The above is the detailed summary of the seven implementation methods of statistical methods in SpringBoot. For more information about the time-consuming statistical methods in SpringBoot, please pay attention to my other related articles!