记录每个方法的执行时间 AOP

34 篇文章 0 订阅
1 篇文章 0 订阅
package com.aop;

import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

public class MyAspect {
		private static final Logger LOGGER=Logger.getLogger(MyAspect.class);
		//输出到指定文件
		//private static final Logger LOGGER=Logger.getLogger("com.util.TimerLogger");

		long a=0;
		public void doBefore(JoinPoint jp) {	  		
			Object[] o=jp.getArgs();
			for(int i=0;i<o.length;i++){
			System.err.println("输入参数为"+o[i]);
			}
			a=System.currentTimeMillis();
			System.err.println("当前方法执行时间为: "
			+ jp.getTarget().getClass().getName() + "."
			+ jp.getSignature().getName());
		}
	  
		public void doAfter(JoinPoint jp) {
			System.err.println("方法结束时间为: "
			+ jp.getTarget().getClass().getName() + "."
			+ jp.getSignature().getName());

			System.err.println("\r<br>执行耗时 : "+(System.currentTimeMillis()-a)+" 秒 ");
		}

		public Object doAround(ProceedingJoinPoint pjp) throws Throwable {

			long time = System.currentTimeMillis();
			Object retVal = pjp.proceed();
			time = System.currentTimeMillis() - time;
			Object[] o=pjp.getArgs();
			for(int i=0;i<o.length;i++){
			LOGGER.info("第"+(i+1)+"输入参数 = "+o[i]);
			}	  
			LOGGER.info("当前方法为 "
			+ pjp.getTarget().getClass().getName() + "."
			+ pjp.getSignature().getName()+"  执行时间为"+time+"ms");
			return retVal;
		}	  

		public void doThrowing(JoinPoint jp, Throwable ex) {
			System.out.println("method " + jp.getTarget().getClass().getName()
			+ "." + jp.getSignature().getName() + " throw exception");
			System.out.println(ex.getMessage());
		}

}

spring配置文件

	<aop:config>	
		<aop:aspect id="concurrentOperationRetry" ref="myAspect">
		<aop:pointcut id="idempotentOperation"
		    expression="execution(* com.service.imp.*.*(..))"/>    
		<!--<aop:before pointcut-ref="idempotentOperation" method="doBefore"/>
		<aop:after pointcut-ref="idempotentOperation" method="doAfter"/> -->
		<aop:around pointcut-ref="idempotentOperation" method="doAround"/>
		</aop:aspect>		
	</aop:config>
测试方法

package function;

import java.io.IOException;


import org.junit.Test;
import com.model.User;
import com.service.UserService;
import com.util.BeanFactoryUtil;

public class MyAspectTest {	
	
	@Test
	public void aopTest() throws IOException{
		
		UserService userservice=(UserService)BeanFactoryUtil.getInstance().getBean("userService");
		User user=userservice.getUserByUid(3);
		System.err.println(user.getName());
	}
}


控制台输出

[30 14:32:22,192 INFO ] [main] imp.UserServiceImpl - UserServiceImpl中getUserByUid执行结束
[30 14:32:22,193 INFO ] [main] aop.MyAspect - 第1输入参数 = 3
[30 14:32:22,194 INFO ] [main] aop.MyAspect - 当前方法为 com.service.imp.UserServiceImpl.getUserByUid  执行时间为459ms

AOP为Aspect Oriented Programming的缩写,意为: 面向切面编程 ,通过 预编译 方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是 OOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是 函数式编程 的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的 耦合度 降低,提高程序的可重用性,同时提高了开发的效率。

配置文件说明

1写切面类。

2定义切入点。 pointcut 指定切入点

3定义通知。(对目标对象进行增强处理)

常用通知类型:
拦截环绕通知 around
前置通知 before
异常通知 after-throwingmethod
后置通知 after


记录com.service.imp.*.*(..))所有方法的执行时间

第一个*记录的是imp包下所有类,第二个*是所有类下的记录所有方法,(..)表示匹配所有的输入参数。

1   目标方法执行前执行切面的around()方法记录当前系统时间为a,

2    执行目标对象方法Object retVal = pjp.proceed();

3    目标方法执行后执行切面的around()方法记录当前系统时间为b

方法执行时间=b-a;

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
具体实现方法如下: 1. 定义一个拦截器类,实现org.aopalliance.intercept.MethodInterceptor接口。 2. 在拦截器类中定义一个切入点,用于确定需要记录方法。 3. 在切入点上定义一个通知,用于记录方法的每条记录。 4. 在通知中,调用日志框架的接口,记录方法的每条记录。 以下是一个示例代码: ```java import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.log4j.Logger; public class LoggingInterceptor implements MethodInterceptor { private static final Logger logger = Logger.getLogger(LoggingInterceptor.class); // 定义切入点 private static final String POINTCUT = "execution(* com.example.service.*.*(..))"; @Override public Object invoke(MethodInvocation invocation) throws Throwable { // 判断方法是否在切入点上 if (invocation.getMethod().getDeclaringClass().getName().matches(POINTCUT)) { // 获取方法参数 Object[] args = invocation.getArguments(); // 记录每条记录 for (Object arg : args) { logger.info("Method: " + invocation.getMethod().getName() + ", Arg: " + arg); } } // 执行方法 Object result = invocation.proceed(); return result; } } ``` 在上述示例代码中,LoggingInterceptor是拦截器类,实现了MethodInterceptor接口。在invoke()方法中,判断方法是否在切入点上,如果是,则记录方法的每条记录。在通知中,调用了Logger类的info()方法记录日志。POINTCUT变量定义了切入点,用于匹配需要记录日志的方法。在这个示例中,POINTCUT匹配com.example.service包下的所有方法。 最后,在Spring配置文件中配置AOP,将LoggingInterceptor作为拦截器,并将其应用于需要记录日志的方法上。以下是一个示例配置: ```xml <bean id="loggingInterceptor" class="com.example.LoggingInterceptor"/> <aop:config> <aop:aspect ref="loggingInterceptor"> <aop:pointcut id="loggingPointcut" expression="execution(* com.example.service.*.*(..))"/> <aop:around method="invoke" pointcut-ref="loggingPointcut"/> </aop:aspect> </aop:config> ``` 在上述配置中,loggingInterceptor是LoggingInterceptor类的实例,用于记录日志。pointcut表达式和LoggingInterceptor类中的POINTCUT变量相同,用于确定需要记录日志的方法。在aop:around标签中,将LoggingInterceptor类的invoke()方法作为通知方法,与loggingPointcut切入点关联起来,用于记录日志。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值