如何使用Spring AOP或AspectJ截取给定方法中的每个方法调用 [英] How to intercept each method call within given method using Spring AOP or AspectJ

查看:155
本文介绍了如何使用Spring AOP或AspectJ截取给定方法中的每个方法调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

 class Test {

@override
public String a(){
b();
d();
}


private String b() {
c();
}

private String c(){
d();
}
private String d(){}

}

我想截获从重写方法A()调用的Test类的每个方法,并想知道每种方法(如b(),c())在分别处理一些业务逻辑时花费了多少时间.

I want to intercept each methods of class Test that is been called from overridden method A() and want to know how much time each method like b(), c() took while processing some business logic separately.

如何使用Spring AOP或Aspectj实现它?

How can I achieve it using Spring AOP or Aspectj?

推荐答案

为了

  • 进入私有方法
  • 在一个类中处理自我调用,
  • 动态确定控制流并将拦截仅限制于您的接口方法直接或间接调用的方法

您需要从Spring AOP(基于代理,很多限制,速度较慢)切换到

you need to switch from Spring AOP (proxy-based, many limitations, slow) to AspectJ using LTW (load-time weaving) as described in the Spring manual.

以下是纯AspectJ(没有Spring,只有Java SE)中的示例,您可以轻松地适应您的需求:

Here is an example in pure AspectJ (no Spring, Just Java SE) which you can easily adapt to your needs:

示例界面

package de.scrum_master.app;

public interface TextTransformer {
  String transform(String text);
}

类实现接口,包括main方法:

Class implementing interface incl. main method:

如您所见,我制作了一个像您一样的示例,并且还使这些方法花费时间,以便以后在方面进行一些测量:

As you can see, I made up an example like yours and also made the methods spend time in order to have something to measure in the aspect later:

package de.scrum_master.app;

public class Application implements TextTransformer {
  @Override
  public String transform(String text) {
    String geekSpelling;
    try {
      geekSpelling = toGeekSpelling(text);
      return toUpperCase(geekSpelling);
    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }

  }

  private String toGeekSpelling(String text) throws InterruptedException {
    Thread.sleep(100);
    return replaceVovels(text).replaceAll("[lL]", "1");
  }

  private String replaceVovels(String text) throws InterruptedException {
    Thread.sleep(75);
    return text.replaceAll("[oO]", "0").replaceAll("[eE]", "Ɛ");
  }

  private String toUpperCase(String text) throws InterruptedException {
    Thread.sleep(50);
    return text.toUpperCase();
  }

  public static void main(String[] args) throws InterruptedException {
    System.out.println(new Application().transform("Hello world!"));
  }
}

方面:

package de.scrum_master.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import static java.lang.System.currentTimeMillis;

@Aspect
public class TimingAspect {
  @Around("execution(* *(..)) && cflow(execution(* de.scrum_master.app.TextTransformer.*(..)))")
  public Object measureExecutionTime(ProceedingJoinPoint thisJoinPoint) throws Throwable {
    long startTime = currentTimeMillis();
    Object result = thisJoinPoint.proceed();
    System.out.println(thisJoinPoint + " -> " + (currentTimeMillis() - startTime) + " ms");
    return result;
  }
}

控制台日志:

execution(String de.scrum_master.app.Application.replaceVovels(String)) -> 75 ms
execution(String de.scrum_master.app.Application.toGeekSpelling(String)) -> 189 ms
execution(String de.scrum_master.app.Application.toUpperCase(String)) -> 63 ms
execution(String de.scrum_master.app.Application.transform(String)) -> 252 ms
HƐ110 W0R1D!

您还可以通过仅将切入点从cflow()更改为cflowbelow()来排除transform(..)方法:

You can also exclude the transform(..) method by just changing the pointcut from cflow() to cflowbelow():

@Around("execution(* *(..)) && cflowbelow(execution(* de.scrum_master.app.TextTransformer.*(..)))")

然后控制台日志就是:

execution(String de.scrum_master.app.Application.replaceVovels(String)) -> 77 ms
execution(String de.scrum_master.app.Application.toGeekSpelling(String)) -> 179 ms
execution(String de.scrum_master.app.Application.toUpperCase(String)) -> 62 ms
HƐ110 W0R1D!

我希望这就是您想要的.很难说,因为您的描述有些含糊.顺便说一句,请务必阅读AspectJ和/或Spring AOP手册.

I hope this is what you wanted. It is hard to tell because your description is somewhat ambiguous. BTW, please do read an AspectJ and/or Spring AOP manual.

这篇关于如何使用Spring AOP或AspectJ截取给定方法中的每个方法调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆