英文:
AOP Isn't hitting the custom annotation
问题 {#heading}
我基本上试图创建一个注解,用于提供任何方法的执行时间。在运行以下代码时,我不确定它是否触发了该方法。此外,IntelliJ 建议"advice advises no method"。
这是我想要它执行的操作 -
import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component;
@Aspect @Component @Slf4j @ConditionalOnExpression("${aspect.enabled:true}") public class ExecutionTimeTracker { @Around(value = "@annotation(TrackExecutionTime)") public Object executionTime(ProceedingJoinPoint point) throws Throwable { long startTime = System.currentTimeMillis(); Object object = point.proceed(); long endTime = System.currentTimeMillis(); log.info(point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName() + " >> Took : " + (endTime - startTime) + "mills"); return object; } }
这是我的 @interface
import java.lang.annotation.Retention; import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ METHOD }) @Retention(RUNTIME) public @interface TrackExecutionTime { }
这是用于测试的单元测试 -
import org.junit.jupiter.api.Test;
public class ExecutionTimeTrackerTest {
@Test @TrackExecutionTime public void someMethod(){ int[] randomNumbers = {582, 15, 596, 827, 779, 426, 153, 557, 394, 12}; Arrays.sort(randomNumbers); int index = Arrays.binarySearch(randomNumbers, 827); Assertions.assertEquals(9, index); }
}
我尝试过将 @Around(value = "@annotation(TrackExecutionTime)")
更改为不同的位置,并尝试使用不同的日志级别设置来执行,但似乎没有任何效果。
英文:
I am basically trying to create an annotation that provides me the execution time of any method. While running the following code, I am not sure if it is hitting the method. Also, intelliJ suggests that "advice advises no method".
This is what I want it to do -
import lombok.extern.slf4j.Slf4j; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; import org.springframework.stereotype.Component;
@Aspect @Component @Slf4j @ConditionalOnExpression("${aspect.enabled:true}") public class ExecutionTimeTracker { @Around(value = "@annotation(TrackExecutionTime)") public Object executionTime(ProceedingJoinPoint point) throws Throwable { long startTime = System.currentTimeMillis(); Object object = point.proceed(); long endtime = System.currentTimeMillis(); log.info(point.getSignature().getDeclaringTypeName() + "." + point.getSignature().getName() + " >> Took : " + (endtime - startTime) + "mills"); return object; }
}
This is my @interface
import java.lang.annotation.Retention; import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ METHOD }) @Retention(RUNTIME) public @interface TrackExecutionTime { }
This is the UT to test this -
import org.junit.jupiter.api.Test;
public class ExecutionTimeTrackerTest {
@Test @TrackExecutionTime public void someMethod(){ int[] randomNumbers = {582, 15, 596, 827, 779, 426, 153, 557, 394, 12}; Arrays.sort(randomNumbers); int index = Arrays.binarySearch(randomNumbers, 827); Assertions.assertEquals(9, index);
}
}
I tried changing @Around(value = "@annotation(TrackExecutionTime)") to different locations, tried executing with setting up different log levels too. Nothing seem to work.
答案1 {#1}
得分: 1
问题在于方面由Spring管理,而您的测试中没有使用Spring。您需要创建一个Spring Boot集成测试才能使其工作。
例如:假设您有以下服务:
@Service
class MyService {
@TrackExecutionTime
public void doSomething() {
// 只是浪费一些时间,假装在做一些有用的事情
for (int i = 0; i < 100_000; i++) {
Math.sqrt(1000);
}
System.out.println("Hello, world");
}
}
然后,您需要以下集成测试(实际上有点无意义,但只是为了向您展示它的工作原理):
@SpringBootTest @RunWith(SpringRunner.class) public class IntegrationTest {
@Autowired MyService myService;
@Test public void testAspect() { myService.doSomething(); }
}
然后,您将在控制台中看到方面被使用:
Hello, world
com.example.MyService.doSomething >> Took : 31mills
英文:
The problem is that the aspect is managed by Spring and you're not using Spring in your test. You need to create a Spring Boot integration test for this to work.
Example: imagine you have this service
@Service
class MyService {
@TrackExecutionTime
public void doSomething() {
// just waste some time pretending to do something useful
for (int i = 0; i < 100_000; i++) {
Math.sqrt(1000);
}
System.out.println("Hello, world");
}
}
then you need the following integration test (a bit of a pointless test to be honest, but it's just to show you how it works):
@SpringBootTest @RunWith(SpringRunner.class) public class IntegrationTest {
@Autowired MyService myService;
@Test public void testAspect() {
myService.doSomething();
}
}
then you'll see that the aspect is used in your console:
Hello, world
com.example.MyService.doSomething >> Took : 31mills