spring aop 实现方法执行时间监控

本文介绍了如何在Mycelipse中创建一个Maven工程,利用Spring AOP和CGlib实现方法执行时间的监控。首先,添加必要的Spring、CGlib和Log4j依赖,接着配置applicationContext-aop.xml并创建AOP切面类。通过打包生成的jar包,可以在其他工程中引用,完成监控功能。主要步骤包括引入jar包、配置应用上下文和日志文件路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发环境

myEclipse ,maven spring

1.在Mycelipse 中创建maven 工程

2.在pom中添加spring依赖

   主要是spring包,cglib包,log4j包等,详细查看pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.cyou</groupId>
	<artifactId>performence-monitor</artifactId>
	<version>1.0-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>performence-monitor</name>
	<url>http://maven.apache.org</url>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<commons-lang.version>2.6</commons-lang.version>
		<spring.version>3.2.4.RELEASE</spring.version>
		<aspectj.version>1.7.3</aspectj.version>
		<cglib.version>3.0</cglib.version>
		<slf4j.version>1.7.7</slf4j.version>
		<log4j.version>1.2.17</log4j.version>
		<junit.version>3.8.1</junit.version>
		<slf4j.version>1.7.7</slf4j.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>${junit.version}</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>${commons-lang.version}</version>
		</dependency>

		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjtools</artifactId>
			<version>${aspectj.version}</version>
		</dependency>

		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>${cglib.version}</version>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>log4j-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>

		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jul-to-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
	</dependencies>
	
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<target>1.6</target>
					<source>1.6</source>
					<encoding>utf-8</encoding>
					<fork>true</fork>
					<meminitial>128m</meminitial>
					<maxmem>512m</maxmem>
					<compilerArguments>
						<verbose />
					</compilerArguments>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


3.在resources创建applicationContext-aop.xml

 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="  
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context   
        http://www.springframework.org/schema/context/spring-context-3.0.xsd
        ">
        
	<context:component-scan base-package="com.henry" />
	<aop:aspectj-autoproxy proxy-target-class="true"/>

</beans>

4.创建aop切面类

/*
 * 文 件 名:  PerformenceMonitor.java
 * 描    述:  <描述>
 * 修 改 人:  Administrator
 * 修改时间:  2014-10-22
 * 跟踪单号:  <跟踪单号>
 * 修改单号:  <修改单号>
 * 修改内容:  <修改内容>
 */
package com.henry.aop;

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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

/**
 * 监控service接口的运行时间
 * <功能详细描述>
 * 
 * @author  Administrator
 * @version  [版本号, 2014-10-22]
 * @see  [相关类/方法]
 * @since  [产品/模块版本]
 */
@Aspect
@Component
public class PerformenceMonitor {
	
	private static final Logger logger = LoggerFactory.getLogger("monitor");
	/**
	 * 监控com.henry.advertising.web.service包及其子包的所有public方法
	 * <功能详细描述>
	 * @see [类、类#方法、类#成员]
	 */
    @Pointcut("execution(* com.henry.advertising.web.service..*.*(..))")  
    private void pointCutMethod() {  
    }  

	 //声明环绕通知  
    @Around("pointCutMethod()")  
    public Object doAround(ProceedingJoinPoint pjp) throws Throwable {  
        long begin = System.nanoTime();
        Object o = pjp.proceed();  
        long end = System.nanoTime();
        logger.debug("{}:{}",pjp.getTarget().getClass()+"."+pjp.getSignature().getName(),(end-begin)/1000000);
        return o;  
    }  
}

5.然后运行maven clean install 打包

这样就生成了一个能够监控方法执行时间的监控。可以对切面类的pointcut重新进行正则,这样就能写出一个通用的监控类


6.在别的工程中引用该jar包,实现监控

  6.1在工程中引入改jar包

     

        <dependency>
			<groupId>com.cyou</groupId>
			<artifactId>performence-monitor</artifactId>
			<version>1.0-SNAPSHOT</version>
		</dependency>

6.2在工程的application.xml中引入该jar包的配置文件

    

<import resource="classpath:/applicationContext-aop.xml"/>

6.3在工程的log4j中配置日志文件路径

   要注意顺序

  

  <appender name="performence.monitor.file" class="org.apache.log4j.DailyRollingFileAppender">
    <param name="file" value="${catalina.home}/logs/performece" />
    <param name="Append" value="true" />
    <param name="encoding" value="UTF-8" />
    <layout class="org.apache.log4j.PatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss,SSS} %r %-5p [%F:%L] : %m%n" />
    </layout>
  </appender>



  <logger name="monitor">
  	<level value="debug" />
  	<appender-ref ref="stdout" />
    <appender-ref ref="performence.monitor.file" />
  </logger>

这样,在启动这个工程的时候,监控模块就能把所拦截的方法执行时间信息打印到指定的文件中,然后供开发人员分析

结果如下:

2014-10-22 12:55:15,249 2541 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:79
2014-10-22 12:55:16,632 3924 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:43
2014-10-22 12:55:17,080 4372 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:17,529 4821 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:47
2014-10-22 12:55:17,973 5265 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:18,416 5708 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:18,868 6160 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:19,314 6606 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:19,757 7049 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:20,203 7495 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:20,647 7939 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:21,088 8380 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:21,531 8823 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:21,975 9267 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:22,416 9708 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:22,867 10159 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:23,322 10614 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:47
2014-10-22 12:55:23,768 11060 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:45
2014-10-22 12:55:24,215 11507 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:44
2014-10-22 12:55:24,662 11954 DEBUG [PerformenceMonitor.java:49] : class com.henry.advertising.web.service.ad.impl.PictureServiceImpl.getPicture:47



<think>好的,用户想了解如何使用Spring Boot AOP实现方法执行日志监控,并需要示例码和实验报告。我需要先回忆一下Spring Boot AOP的相关知识。首先,AOP(面向切面编程)是用来在程序运行期间动态地将码切入到类的指定方法或位置的编程思想。在Spring Boot中,可以通过AOP来拦截方法执行记录日志,比如方法的开始、结束时间,参数,返回值等。 用户提到的日志监控,应该是在方法执行前后记录相关信息。可能需要使用@Around注解来定义切面,这样可以在方法执行前后添加逻辑。同时,需要确保项目中引入了Spring Boot的AOP依赖,通常是spring-boot-starter-aop。 然后,考虑示例码的结构。首先在pom.xml中添加AOP的依赖,然后创建一个自定义注解,比如@LogExecution,用来标记需要监控方法。接着,编写切面类,使用@Aspect注解,定义切点表达式,针对带有@LogExecution注解的方法进行拦截。在切面中,使用@Around通知,记录方法执行时间、参数、返回结果等信息。 另外,用户可能需要配置日志框架,比如Logback,来输出日志信息。根据用户提供的引用,Spring Boot默认使用Logback,可以通过logback.xml配置文件来自定义日志格式和输出方式。在配置文件中,可能需要设置日志级别为DEBUG,以便查看AOP拦截的详细信息。 实验报告部分,应该包括实验目的、环境、步骤、结果分析等。需要指导用户如何搭建项目,添加依赖,编写码,运行并测试日志输出是否正常。可能还需要说明如何通过debug模式查看自动配置的生效情况,如引用3中提到的设置debug=true来查看哪些自动配置类被启用。 需要注意的地方包括:确保AOP依赖正确引入,切面类的正确注解,以及日志配置的有效性。此外,如果用户需要监控所有方法,而不仅仅是带有特定注解的,可以调整切点表达式,例如使用execution(* com.example..*.*(..))来匹配特定包下的所有方法。 最后,用户可能遇到的问题包括切面不生效,这时候需要检查是否启用了AOP,或者切点表达式是否正确。另外,日志输出可能需要调整级别或格式,确保相关信息被正确记录。可能还需要引用用户提供的引用内容,比如如何配置日志文件或自定义健康指标,但当前问题主要围绕AOP和日志监控,因此重点应放在相关部分。</think>### Spring Boot AOP实现方法执行日志监控的步骤与示例 #### 一、核心依赖配置 在`pom.xml`中添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </dependency> ``` Spring Boot默认集成Logback作为日志框架[^2]。 --- #### 二、自定义注解(标记需监控方法) ```java @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogExecution { } ``` --- #### 三、实现AOP切面 ```java @Aspect @Component public class LoggingAspect { private static final Logger logger = LoggerFactory.getLogger(LoggingAspect.class); // 定义切点为带有@LogExecution注解的方法 @Pointcut("@annotation(com.example.demo.annotation.LogExecution)") public void logPointcut() {} // 环绕通知记录方法执行时间、参数和返回值 @Around("logPointcut()") public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable { long startTime = System.currentTimeMillis(); String methodName = joinPoint.getSignature().getName(); Object[] args = joinPoint.getArgs(); // 记录方法调用信息 logger.debug("方法 {} 开始执行 | 参数: {}", methodName, Arrays.toString(args)); Object result = joinPoint.proceed(); // 执行目标方法 long executionTime = System.currentTimeMillis() - startTime; logger.debug("方法 {} 执行成 | 耗时: {}ms | 返回值: {}", methodName, executionTime, result); return result; } } ``` --- #### 四、配置日志输出(logback.xml示例) ```xml <configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> </root> </configuration> ``` 通过配置`logback.xml`可自定义日志格式和输出方式[^1]。 --- #### 五、实验报告要点 1. **实验目的** 验证AOP切面能否正确拦截目标方法记录执行日志。 2. **测试用例** ```java @Service public class DemoService { @LogExecution public String processData(String input) { return "Processed: " + input.toUpperCase(); } } ``` 3. **验证步骤** - 调用`processData("test")` - 观察控制台输出: ``` 2023-09-01 14:30:00 [http-nio-8080-exec-1] DEBUG com.example.demo.aspect.LoggingAspect - 方法 processData 开始执行 | 参数: [test] 2023-09-01 14:30:00 [http-nio-8080-exec-1] DEBUG com.example.demo.aspect.LoggingAspect - 方法 processData 执行成 | 耗时: 2ms | 返回值: Processed: TEST ``` 4. **性能分析** 可通过调整日志级别(如`INFO`减少输出量)或添加条件判断优化日志记录频率。 --- #### 六、常见问题 1. **切面生效** 检查是否添加`@EnableAspectJAutoProxy`(Spring Boot默认自动启用),或切点表达式是否匹配目标方法2. **日志输出** 确认`application.properties`中设置`debug=true`以启用调试模式[^3]。 3. **扩展功能** 可结合自定义健康指标(实现`HealthIndicator`接口[^4])监控系统状态。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值