gpt4 book ai didi

java - 如何使用 Spring AOP 或 AspectJ 拦截给定方法中的每个方法调用

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:33:20 25 4
gpt4 key购买 nike

 class Test {

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


private String b() {
c();
}

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

}

我想拦截从覆盖方法 A() 调用的类 Test 的每个方法,并想知道每个方法(如 b()、c())在分别处理某些业务逻辑时花费了多少时间。

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

最佳答案

为了

  • 编织成私有(private)方法,
  • 在一个类中处理自调用,
  • 动态确定控制流并将拦截限制为仅由您的接口(interface)方法直接或间接调用的方法

您需要从 Spring AOP(基于代理,许多限制,缓慢)切换到 AspectJ using LTW (load-time weaving)如 Spring 手册中所述。

这是一个纯 AspectJ 示例(没有 Spring,只有 Java SE),您可以轻松地适应您的需要:

示例界面

package de.scrum_master.app;

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

实现接口(interface)的类,包括。 主要方法:

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

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(..) 方法:

@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 手册。

关于java - 如何使用 Spring AOP 或 AspectJ 拦截给定方法中的每个方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49159666/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com