最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot中統(tǒng)計(jì)方法耗時(shí)的七種實(shí)現(xiàn)方式小結(jié)

 更新時(shí)間:2025年03月28日 11:31:13   作者:風(fēng)象南  
作為開(kāi)發(fā)者,我們經(jīng)常需要統(tǒng)計(jì)方法的執(zhí)行時(shí)間,以便找出性能瓶頸,優(yōu)化系統(tǒng)響應(yīng)速度,今天分享在SpringBoot框架中實(shí)現(xiàn)方法耗時(shí)統(tǒng)計(jì)的幾種方法,大家可以根據(jù)需求自行選擇

一、手動(dòng)使用StopWatch

最直接的方法是使用Spring提供的StopWatch類(lèi),這種方式簡(jiǎn)單直觀,適合臨時(shí)性的性能測(cè)試。

import org.springframework.util.StopWatch;

@Service
public class UserService {
    
    public User findUserById(Long id) {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        
        // 業(yè)務(wù)邏輯
        User user = userRepository.findById(id).orElse(null);
        
        stopWatch.stop();
        System.out.println("findUserById方法耗時(shí):" + stopWatch.getTotalTimeMillis() + "ms");
        
        return user;
    }
}

優(yōu)點(diǎn):簡(jiǎn)單直觀,無(wú)需額外配置

缺點(diǎn):侵入業(yè)務(wù)代碼,不夠優(yōu)雅,需要手動(dòng)添加到每個(gè)需要監(jiān)控的方法

二、使用AOP實(shí)現(xiàn)全局方法耗時(shí)統(tǒng)計(jì)

AOP(面向切面編程)是實(shí)現(xiàn)方法耗時(shí)統(tǒng)計(jì)的理想選擇,它可以在不修改原有代碼的情況下,統(tǒng)一處理耗時(shí)統(tǒng)計(jì)邏輯。

首先,添加AOP依賴(lài):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

然后,創(chuàng)建切面類(lèi):

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class MethodTimeAspect {
    
    @Pointcut("execution(* com.example.demo.service.*.*(..))")
    public void serviceMethodPointcut() {}
    
    @Around("serviceMethodPointcut()")
    public Object timeAround(ProceedingJoinPoint joinPoint) throws Throwable {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        
        // 執(zhí)行目標(biāo)方法
        Object result = joinPoint.proceed();
        
        stopWatch.stop();
        String methodName = joinPoint.getSignature().getName();
        System.out.println("方法[" + methodName + "]耗時(shí):" + stopWatch.getTotalTimeMillis() + "ms");
        
        return result;
    }
}

優(yōu)點(diǎn):代碼無(wú)侵入,統(tǒng)一管理,配置靈活

缺點(diǎn):對(duì)于特定方法的定制化需求不夠靈活

三、自定義注解+AOP實(shí)現(xiàn)更精細(xì)的控制

這種方法結(jié)合了自定義注解和AOP,可以更精確地控制哪些方法需要進(jìn)行耗時(shí)統(tǒng)計(jì)。

首先,創(chuàng)建自定義注解:

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface TimeLog {
    String value() default "";
}

然后,創(chuàng)建切面類(lèi)處理帶有該注解的方法:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;

@Aspect
@Component
public class TimeLogAspect {
    
    @Around("@annotation(com.example.demo.annotation.TimeLog)")
    public Object timeLogAround(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        TimeLog timeLog = signature.getMethod().getAnnotation(TimeLog.class);
        
        String methodDesc = timeLog.value().isEmpty() ? 
                signature.getMethod().getName() : timeLog.value();
        
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        
        Object result = joinPoint.proceed();
        
        stopWatch.stop();
        System.out.println("方法[" + methodDesc + "]耗時(shí):" + stopWatch.getTotalTimeMillis() + "ms");
        
        return result;
    }
}

使用示例:

@Service
public class ProductService {
    
    @TimeLog("查詢(xún)商品詳情")
    public Product getProductDetail(Long id) {
        // 業(yè)務(wù)邏輯
        return productRepository.findById(id).orElse(null);
    }
}

優(yōu)點(diǎn):更精細(xì)的控制,注解可攜帶更多信息,便于定制

缺點(diǎn):需要手動(dòng)在方法上添加注解

四、使用攔截器統(tǒng)計(jì)Controller接口耗時(shí)

如果只關(guān)注Controller層的接口耗時(shí),可以使用Spring的攔截器:

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

@Component
public class ApiTimeInterceptor implements HandlerInterceptor {
    
    private ThreadLocal<Long> startTime = new ThreadLocal<>();
    
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        startTime.set(System.currentTimeMillis());
        return true;
    }
    
    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime.get();
        String uri = request.getRequestURI();
        System.out.println("接口[" + uri + "]耗時(shí):" + executionTime + "ms");
        startTime.remove();
    }
}

注冊(cè)攔截器:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {
    
    private final ApiTimeInterceptor apiTimeInterceptor;
    
    public WebConfig(ApiTimeInterceptor apiTimeInterceptor) {
        this.apiTimeInterceptor = apiTimeInterceptor;
    }
    
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(apiTimeInterceptor).addPathPatterns("/api/");
    }
}

優(yōu)點(diǎn):專(zhuān)注于Web接口性能,對(duì)接口進(jìn)行統(tǒng)一監(jiān)控

缺點(diǎn):只能監(jiān)控Controller層方法,無(wú)法監(jiān)控內(nèi)部服務(wù)方法

五、使用Actuator + Micrometer實(shí)現(xiàn)細(xì)粒度監(jiān)控

Spring Boot Actuator提供了與Micrometer的集成,可以實(shí)現(xiàn)更專(zhuān)業(yè)的性能指標(biāo)收集:

添加依賴(lài):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>io.micrometer</groupId>
    <artifactId>micrometer-registry-prometheus</artifactId>
</dependency>

使用Micrometer進(jìn)行方法計(jì)時(shí):

import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.Timer;
import org.springframework.stereotype.Service;

@Service
public class OrderService {
    
    private final MeterRegistry meterRegistry;
    
    public OrderService(MeterRegistry meterRegistry) {
        this.meterRegistry = meterRegistry;
    }
    
    public Order createOrder(OrderRequest request) {
        Timer.Sample sample = Timer.start(meterRegistry);
        
        // 業(yè)務(wù)邏輯
        Order order = processOrder(request);
        
        sample.stop(meterRegistry.timer("order.creation.time"));
        
        return order;
    }
}

配置Actuator暴露指標(biāo):

management:
  endpoints:
    web:
      exposure:
        include: metrics,prometheus
  metrics:
    export:
      prometheus:
        enabled: true

優(yōu)點(diǎn):專(zhuān)業(yè)的性能指標(biāo)收集,可與Prometheus、Grafana等監(jiān)控系統(tǒng)集成,適合生產(chǎn)環(huán)境

缺點(diǎn):配置相對(duì)復(fù)雜,有一定學(xué)習(xí)成本

六、使用Filter實(shí)現(xiàn)請(qǐng)求耗時(shí)統(tǒng)計(jì)

創(chuàng)建一個(gè)Filter實(shí)現(xiàn)類(lèi),可以記錄每次HTTP請(qǐng)求的開(kāi)始時(shí)間和結(jié)束時(shí)間,從而計(jì)算出請(qǐng)求的整體耗時(shí)。

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

@Component
public class TimingFilter implements Filter {
    
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        long startTime = System.currentTimeMillis();
        
        // 繼續(xù)處理請(qǐng)求
        chain.doFilter(request, response);
        
        long endTime = System.currentTimeMillis();
        long executionTime = endTime - startTime;
        String requestUri = ((HttpServletRequest) request).getRequestURI();
        System.out.println("請(qǐng)求[" + requestUri + "]耗時(shí):" + executionTime + "ms");
    }
    
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}
    
    @Override
    public void destroy() {}
}

優(yōu)點(diǎn):可以全局監(jiān)控所有Web請(qǐng)求的耗時(shí)。

缺點(diǎn):只提供整體請(qǐng)求的耗時(shí),無(wú)法深入到具體業(yè)務(wù)邏輯的執(zhí)行時(shí)間。

七、使用ServletRequestHandledEvent統(tǒng)計(jì)請(qǐng)求處理耗時(shí)

Spring Boot提供了ServletRequestHandledEvent事件,可以用來(lái)監(jiān)控HTTP請(qǐng)求的處理時(shí)間。這種方式適合于全局監(jiān)控所有的請(qǐng)求。

首先,創(chuàng)建事件監(jiān)聽(tīng)器:

import org.springframework.context.ApplicationListener;
import org.springframework.web.context.request.ServletRequestHandledEvent;
import org.springframework.stereotype.Component;

@Component
public class RequestTimingListener implements ApplicationListener<ServletRequestHandledEvent> {

    @Override
    public void onApplicationEvent(ServletRequestHandledEvent event) {
        System.out.println("請(qǐng)求[" + event.getRequestUrl() + "]耗時(shí):" + event.getProcessingTimeMillis() + "ms");
    }
}

這種方法會(huì)自動(dòng)監(jiān)聽(tīng)處理結(jié)果,不需要在每個(gè)Controller中進(jìn)行顯式的耗時(shí)統(tǒng)計(jì)。

優(yōu)點(diǎn):不需要修改現(xiàn)有代碼,監(jiān)控全局請(qǐng)求的耗時(shí)
缺點(diǎn):不支持自定義請(qǐng)求的粒度控制

總結(jié)與對(duì)比

在SpringBoot中,以上七種方法各有優(yōu)缺點(diǎn),可以根據(jù)不同的場(chǎng)景選擇合適的方案:

  • StopWatch手動(dòng)統(tǒng)計(jì):適合臨時(shí)測(cè)試,快速實(shí)現(xiàn)
  • 全局AOP:適合對(duì)整個(gè)服務(wù)層進(jìn)行性能監(jiān)控
  • 自定義注解+AOP:適合精細(xì)化控制,只監(jiān)控關(guān)鍵方法
  • 攔截器:適合Web接口監(jiān)控
  • Actuator+Micrometer:適合生產(chǎn)環(huán)境,與專(zhuān)業(yè)監(jiān)控系統(tǒng)集成
  • Filter:適合全局請(qǐng)求監(jiān)控,輕量級(jí)實(shí)現(xiàn)
  • ServletRequestHandledEvent:全局監(jiān)控HTTP請(qǐng)求處理時(shí)間,不需改動(dòng)代碼

以上就是SpringBoot中統(tǒng)計(jì)方法耗時(shí)的七種實(shí)現(xiàn)方式小結(jié)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot統(tǒng)計(jì)方法耗時(shí)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 詳解微信開(kāi)發(fā)之a(chǎn)ccess_token之坑

    詳解微信開(kāi)發(fā)之a(chǎn)ccess_token之坑

    access_token分類(lèi)一是普通access_token,二是網(wǎng)頁(yè)授權(quán)access_token。這篇文章主要介紹了詳解微信開(kāi)發(fā)之a(chǎn)ccess_token之坑,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-10-10
  • Mybatis?plus?where添加括號(hào)方式

    Mybatis?plus?where添加括號(hào)方式

    這篇文章主要介紹了Mybatis?plus?where添加括號(hào)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • 批量將現(xiàn)有Jar包上傳到Maven私服

    批量將現(xiàn)有Jar包上傳到Maven私服

    今天小編就為大家分享一篇關(guān)于批量將現(xiàn)有Jar包上傳到Maven私服,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2018-12-12
  • 關(guān)于@MapperScan包掃描的坑及解決

    關(guān)于@MapperScan包掃描的坑及解決

    這篇文章主要介紹了關(guān)于@MapperScan包掃描的坑及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • Java中常用的9種文件下載方法總結(jié)

    Java中常用的9種文件下載方法總結(jié)

    下載文件在我們項(xiàng)目很常見(jiàn),有下載視頻、文件、圖片、附件、導(dǎo)出Excel等,所以本文為大家整理了9中Java中常用的文件下載方式,希望對(duì)大家有所幫助
    2023-09-09
  • Struts2實(shí)現(xiàn)CRUD(增 刪 改 查)功能實(shí)例代碼

    Struts2實(shí)現(xiàn)CRUD(增 刪 改 查)功能實(shí)例代碼

    CRUD是Create(創(chuàng)建)、Read(讀?。?、Update(更新)和Delete(刪除)的縮寫(xiě),它是普通應(yīng)用程序的縮影。接下來(lái)通過(guò)本文給大家介紹Struts2實(shí)現(xiàn)CRUD(增 刪 改 查)功能實(shí)例代碼,感興趣的朋友一起看看吧
    2016-06-06
  • idea項(xiàng)目文件夾橫向顯示,縱向顯示的解決方法

    idea項(xiàng)目文件夾橫向顯示,縱向顯示的解決方法

    這篇文章主要介紹了idea項(xiàng)目文件夾橫向顯示,縱向顯示的解決方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-08-08
  • mybatis配置文件簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    mybatis配置文件簡(jiǎn)介_(kāi)動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要為大家詳細(xì)介紹了mybatis配置文件簡(jiǎn)介的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-09-09
  • Spring中@Autowired自動(dòng)注入map詳解

    Spring中@Autowired自動(dòng)注入map詳解

    這篇文章主要介紹了Spring中@Autowired自動(dòng)注入map詳解,  spring是支持基于接口實(shí)現(xiàn)類(lèi)的直接注入的,支持注入map,list等集合中,不用做其他的配置,直接注入,需要的朋友可以參考下
    2023-10-10
  • Mybatis-Mapper.xml文件前綴詳解

    Mybatis-Mapper.xml文件前綴詳解

    這篇文章主要介紹了Mybatis-Mapper.xml文件前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評(píng)論

中西区| 高密市| 诸城市| 黑山县| 兴文县| 盐亭县| 临洮县| 福州市| 乌什县| 历史| 云梦县| 通海县| 赤水市| 平塘县| 邻水| 永嘉县| 台州市| 淳安县| 洛川县| 嵊州市| 八宿县| 邯郸县| 衡东县| 泽普县| 博客| 卢龙县| 屯门区| 杂多县| 景东| 石屏县| 玛曲县| 罗平县| 镇平县| 屏南县| 汾阳市| 宁安市| 桃园县| 西平县| 永州市| 新丰县| 阜城县|