AOP没有触发自定义注解。

huangapple go评论198阅读模式
英文:

AOP Isn't hitting the custom annotation

问题

我基本上试图创建一个注解,用于提供任何方法的执行时间。在运行以下代码时,我不确定它是否触发了该方法。此外,IntelliJ 建议“advice advises no method”。

这是我想要它执行的操作 -

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.Around;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  6. import org.springframework.stereotype.Component;
  7. @Aspect
  8. @Component
  9. @Slf4j
  10. @ConditionalOnExpression("${aspect.enabled:true}")
  11. public class ExecutionTimeTracker {
  12. @Around(value = "@annotation(TrackExecutionTime)")
  13. public Object executionTime(ProceedingJoinPoint point) throws Throwable {
  14. long startTime = System.currentTimeMillis();
  15. Object object = point.proceed();
  16. long endTime = System.currentTimeMillis();
  17. log.info(point.getSignature().getDeclaringTypeName() +
  18. "." + point.getSignature().getName() +
  19. " >> Took : " + (endTime - startTime) + "mills");
  20. return object;
  21. }
  22. }

这是我的 @interface

  1. import java.lang.annotation.Retention;
  2. import java.lang.annotation.Target;
  3. import static java.lang.annotation.ElementType.METHOD;
  4. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  5. @Target({ METHOD })
  6. @Retention(RUNTIME)
  7. public @interface TrackExecutionTime {
  8. }

这是用于测试的单元测试 -

  1. import org.junit.jupiter.api.Test;
  2. public class ExecutionTimeTrackerTest {
  3. @Test
  4. @TrackExecutionTime
  5. public void someMethod(){
  6. int[] randomNumbers = {582, 15, 596, 827, 779, 426, 153, 557, 394, 12};
  7. Arrays.sort(randomNumbers);
  8. int index = Arrays.binarySearch(randomNumbers, 827);
  9. Assertions.assertEquals(9, index);
  10. }
  11. }

我尝试过将 @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 -

  1. import lombok.extern.slf4j.Slf4j;
  2. import org.aspectj.lang.ProceedingJoinPoint;
  3. import org.aspectj.lang.annotation.Around;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
  6. import org.springframework.stereotype.Component;
  7. @Aspect
  8. @Component
  9. @Slf4j
  10. @ConditionalOnExpression("${aspect.enabled:true}")
  11. public class ExecutionTimeTracker {
  12. @Around(value = "@annotation(TrackExecutionTime)")
  13. public Object executionTime(ProceedingJoinPoint point) throws Throwable {
  14. long startTime = System.currentTimeMillis();
  15. Object object = point.proceed();
  16. long endtime = System.currentTimeMillis();
  17. log.info(point.getSignature().getDeclaringTypeName() +
  18. "." + point.getSignature().getName() +
  19. " >> Took : " + (endtime - startTime) + "mills");
  20. return object;
  21. }
  22. }

This is my @interface

  1. import java.lang.annotation.Retention;
  2. import java.lang.annotation.Target;
  3. import static java.lang.annotation.ElementType.METHOD;
  4. import static java.lang.annotation.RetentionPolicy.RUNTIME;
  5. @Target({ METHOD })
  6. @Retention(RUNTIME)
  7. public @interface TrackExecutionTime {
  8. }

This is the UT to test this -

  1. import org.junit.jupiter.api.Test;
  2. public class ExecutionTimeTrackerTest {
  3. @Test
  4. @TrackExecutionTime
  5. public void someMethod(){
  6. int[] randomNumbers = {582, 15, 596, 827, 779, 426, 153, 557, 394, 12};
  7. Arrays.sort(randomNumbers);
  8. int index = Arrays.binarySearch(randomNumbers, 827);
  9. Assertions.assertEquals(9, index);
  10. }
  11. }

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

问题在于方面由Spring管理,而您的测试中没有使用Spring。您需要创建一个Spring Boot集成测试才能使其工作。

例如:假设您有以下服务:

  1. @Service
  2. class MyService {
  3. @TrackExecutionTime
  4. public void doSomething() {
  5. // 只是浪费一些时间,假装在做一些有用的事情
  6. for (int i = 0; i < 100_000; i++) {
  7. Math.sqrt(1000);
  8. }
  9. System.out.println("Hello, world");
  10. }
  11. }

然后,您需要以下集成测试(实际上有点无意义,但只是为了向您展示它的工作原理):

  1. @SpringBootTest
  2. @RunWith(SpringRunner.class)
  3. public class IntegrationTest {
  4. @Autowired
  5. MyService myService;
  6. @Test
  7. public void testAspect() {
  8. myService.doSomething();
  9. }
  10. }

然后,您将在控制台中看到方面被使用:

  1. Hello, world
  2. 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

  1. @Service
  2. class MyService {
  3. @TrackExecutionTime
  4. public void doSomething() {
  5. // just waste some time pretending to do something useful
  6. for (int i = 0; i < 100_000; i++) {
  7. Math.sqrt(1000);
  8. }
  9. System.out.println("Hello, world");
  10. }
  11. }

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):

  1. @SpringBootTest
  2. @RunWith(SpringRunner.class)
  3. public class IntegrationTest {
  4. @Autowired
  5. MyService myService;
  6. @Test
  7. public void testAspect() {
  8. myService.doSomething();
  9. }
  10. }

then you'll see that the aspect is used in your console:

  1. Hello, world
  2. com.example.MyService.doSomething >> Took : 31mills

huangapple
  • 本文由 发表于 2023年8月10日 17:30:57
  • 转载请务必保留本文链接:https://go.coder-hub.com/76874424.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定