知識庫 / Spring RSS 訂閱

Spring 性能日誌

Logging,Spring
HongKong
4
02:42 PM · Dec 06 ,2025

1. 概述

在本教程中,我們將探討 Spring Framework 為性能監控提供的幾個基本選項。

2.

一個簡單的解決方案,用於獲取我們方法執行時間的基本監控功能,我們可以利用 Spring AOP(面向切面編程)中的 類。

Spring AOP 允許在應用程序中定義橫切關注點,這意味着可以攔截一個或多個方法的執行,以便添加額外的功能。

類是一個攔截器,可以與任何自定義方法關聯,以便在方法執行的同時執行。該類使用一個 實例來確定方法的開始時間和結束時間。

讓我們創建一個簡單的 類和一個 類,其中包含兩個我們將進行監控的方法:

public class Person {
    private String lastName;
    private String firstName;
    private LocalDate dateOfBirth;

    // standard constructors, getters, setters
}
public class PersonService {
    
    public String getFullName(Person person){
        return person.getLastName()+" "+person.getFirstName();
    }
    
    public int getAge(Person person){
        Period p = Period.between(person.getDateOfBirth(), LocalDate.now());
        return p.getYears();
    }
}

為了充分利用 Spring 監控攔截器,我們需要定義一個切入點和顧問:

@Configuration
@EnableAspectJAutoProxy
@Aspect
public class AopConfiguration {
    
    @Pointcut(
      "execution(public String com.baeldung.performancemonitor.PersonService.getFullName(..))"
    )
    public void monitor() { }
    
    @Bean
    public PerformanceMonitorInterceptor performanceMonitorInterceptor() {
        return new PerformanceMonitorInterceptor(true);
    }

    @Bean
    public Advisor performanceMonitorAdvisor() {
        AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
        pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.monitor()");
        return new DefaultPointcutAdvisor(pointcut, performanceMonitorInterceptor());
    }
    
    @Bean
    public Person person(){
        return new Person("John","Smith", LocalDate.of(1980, Month.JANUARY, 12));
    }
 
    @Bean
    public PersonService personService(){
        return new PersonService();
    }
}

切面包含一個表達式,用於識別我們希望攔截的方法——在本例中是 PersonService 類中 getFullName() 方法。

配置 performanceMonitorInterceptor() Bean 後,我們需要將攔截器與切面關聯起來。這通過 Advisor 實現,如上例所示。

最後,@EnableAspectJAutoProxy 註解啓用了 AspectJ 支持,以便我們對 Bean 進行支持。簡單來説,AspectJ 是一個庫,旨在通過方便的註解(如 @Pointcut)使 Spring AOP 更容易使用。

配置完成後,我們需要將攔截器類的日誌級別設置為 TRACE,因為這是它記錄消息的級別。

例如,使用 Jog4j,我們可以通過 log4j.properties 文件來實現這一點:

log4j.logger.org.springframework.aop.interceptor.PerformanceMonitorInterceptor=TRACE, stdout

對於 getAge() 方法的每次執行,您將在控制枱日誌中看到 TRACE 消息:

2017-01-08 19:19:25 TRACE 
  PersonService:66 - StopWatch 
  'com.baeldung.performancemonitor.PersonService.getFullName': 
  running time (millis) = 10

3. 自定義性能監控攔截器為了獲得對性能監控的更多控制,我們可以實現自定義攔截器。

為此,我們應該擴展 AbstractMonitoringInterceptor 類並覆蓋 invokeUnderTrace() 方法,以記錄方法的開始、結束和持續時間,以及如果方法執行時間超過 10 毫秒的警告。

public class MyPerformanceMonitorInterceptor extends AbstractMonitoringInterceptor {
    
    public MyPerformanceMonitorInterceptor() {
    }

    public MyPerformanceMonitorInterceptor(boolean useDynamicLogger) {
            setUseDynamicLogger(useDynamicLogger);
    }

    @Override
    protected Object invokeUnderTrace(MethodInvocation invocation, Log log) 
      throws Throwable {
        String name = createInvocationTraceName(invocation);
        long start = System.currentTimeMillis();
        log.info("Method " + name + " execution started at:" + new Date());
        try {
            return invocation.proceed();
        }
        finally {
            long end = System.currentTimeMillis();
            long time = end - start;
            log.info("Method "+name+" execution lasted:"+time+" ms");
            log.info("Method "+name+" execution ended at:"+new Date());
            
            if (time > 10){
                log.warn("Method execution longer than 10 ms!");
            }            
        }
    }
}

遵循前一節中將自定義攔截器與一個或多個方法關聯的相同步驟。

讓我們為getAge()方法定義一個切入點,該方法位於PersonService中,並將該切入點與我們創建的攔截器關聯起來:

@Pointcut("execution(public int com.baeldung.performancemonitor.PersonService.getAge(..))")
public void myMonitor() { }
    
@Bean
public MyPerformanceMonitorInterceptor myPerformanceMonitorInterceptor() {
    return new MyPerformanceMonitorInterceptor(true);
}
    
@Bean
public Advisor myPerformanceMonitorAdvisor() {
    AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
    pointcut.setExpression("com.baeldung.performancemonitor.AopConfiguration.myMonitor()");
    return new DefaultPointcutAdvisor(pointcut, myPerformanceMonitorInterceptor());
}

讓我們將日誌級別設置為 INFO 以供自定義攔截器使用:

log4j.logger.com.baeldung.performancemonitor.MyPerformanceMonitorInterceptor=INFO, stdout

執行 g<em>etAge()</em> 方法 產生以下輸出:

2017-01-08 19:19:25 INFO PersonService:26 - 
  Method com.baeldung.performancemonitor.PersonService.getAge 
  execution started at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 INFO PersonService:33 - 
  Method com.baeldung.performancemonitor.PersonService.getAge execution lasted:50 ms
2017-01-08 19:19:25 INFO PersonService:34 - 
  Method com.baeldung.performancemonitor.PersonService.getAge 
  execution ended at:Sun Jan 08 19:19:25 EET 2017
2017-01-08 19:19:25 WARN PersonService:37 - 
  Method execution longer than 10 ms!

4. 結論

在本快速教程中,我們介紹了在 Spring 中進行簡單性能監控的方法。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.