Spring 如何在@Aspect类内调用@RateLimiter注释

Spring 如何在@Aspect类内调用@RateLimiter注释,spring,aop,resilience4j,Spring,Aop,Resilience4j,我试图在一个方面类中实现弹性逻辑,类似于日志记录的实现方式。下面是我一直在尝试的一段代码,但它不起作用 @Pointcut("within(com.example.demo.*)") public void myPointCut() { } @Around("myPointCut()") public String addfaultToleranceRateLimiter(ProceedingJoinPoint pj) throws Throwable,Illega

我试图在一个方面类中实现弹性逻辑,类似于日志记录的实现方式。下面是我一直在尝试的一段代码,但它不起作用

  @Pointcut("within(com.example.demo.*)")
   public void myPointCut() {

  }
  @Around("myPointCut()")
  public String addfaultToleranceRateLimiter(ProceedingJoinPoint pj) throws 
  Throwable,IllegalAccessException,InvocationTargetException {
     String result = applyRLtolerance(pj);
     return result;
  }
  @RateLimiter(name="service1",fallbackMethod = "fallbackRL")
  private String applyRLtolerance(ProceedingJoinPoint pj) throws Throwable {
    String result = (String) pj.proceed();
    return result;
  }

 public String fallbackRL(Throwable t) {
        System.out.println("in fallback" + new Date());
        return "bye";
      }

当pj.继续()时调用实际逻辑,但@ratelimiter注释似乎不起作用,因为根据application.yml文件中给出的配置,执行的调用数没有受到限制。

如果在同一类中调用注释方法,而注释不在同一类中,则大多数注释都使用AOP处理效果。当多个方面满足执行标准时,AOP也会出现顺序问题

在本例中,您是从同一个类调用该方法,因此注释无效。您可以通过将与速率限制器相关的方法移动到另一个类来解决此问题

class MyAspect{
   RateLimiterSercvice rls = new RateLimiterSercvice();
   @Pointcut("within(com.example.demo.*)")
   public void myPointCut() {

   }
   @Around("myPointCut()")
   public String addfaultToleranceRateLimiter(ProceedingJoinPoint pj) throws 
    Throwable,IllegalAccessException,InvocationTargetException {
     String result = rls.applyRLtolerance(pj);
     return result;
  }
}


class RateLimiterService {
  @RateLimiter(name="service1",fallbackMethod = "fallbackRL")
  public String applyRLtolerance(ProceedingJoinPoint pj) throws Throwable {
    String result = (String) pj.proceed();
    return result;
  }
  public String fallbackRL(Throwable t) {
        System.out.println("in fallback" + new Date());
        return "bye";
  }
}





您需要将包装器类配置为Springbean,并在
方面将其自动连接

由于以下原因,该代码不起作用

  • 当使用
    new
    关键字创建实例时,它不是spring管理的bean
  • Spring AOP无法拦截/通知内部方法调用
  • 下面的代码有效

    @Aspect
    @Component
    public class ResilienceAspect {
    
        @Autowired
        ResilienceWrapper wrapper;
    
        @Pointcut("within(com.example.demo.*)")
        public void myPointCut() {
    
        }
    
        @Around("myPointCut()")
        public String addfaultToleranceRateLimiter(ProceedingJoinPoint pj)
                throws Throwable, IllegalAccessException, InvocationTargetException {
            String result = wrapper.applyRLtolerance(pj);
            return result;
        }
    }
    
    包装纸

    @Component
    public class ResilienceWrapper {
    
        @RateLimiter(name = "service1", fallbackMethod = "fallbackRL")
        public String applyRLtolerance(ProceedingJoinPoint pj) throws Throwable {
            String result = (String) pj.proceed();
            return result;
        }
    
        public String fallbackRL(Throwable t) {
            System.out.println("in fallback" + new Date());
            return "bye";
        }
    }
    
    请注意:

    (com.example.demo.*)中的
    可以进行调整,使其不会干扰方面代码。如果
    resiliencespect
    也在
    com.example.demo
    中,则运行将产生不希望的结果


    希望这能有所帮助。

    我尝试将rateLimiter相关的方法移动到另一个类。它不起作用。是自定义注释吗?不是downvoter。尝试的方法似乎不正确。请仔细阅读以了解正确用法。请注意,
    resilience4j
    本身是基于AOP的。RateLimiter是作为resilience4j库的一部分构建的注释。我试图在Resilience4j库的基础上构建一个包装器,这样导入包装器的客户端就不必担心Resilience4j库的复杂性。这就是我试图构建一个方面,然后在其中调用弹性注释的原因,这样客户机就不必自己去做了。与日志记录的实现方式类似。这将有助于将客户机代码和弹性代码分开。您能用project pom.xml更新这个问题吗?而且,我意识到是我否决了这个问题,这不是故意的。我试图恢复相同的内容,但在问题再次编辑之前无法恢复。如果你能帮忙的话,我想纠正我的错误。