繁体   English   中英

@Autowired:没有可用的 SpringBoot 应用程序类型的合格 bean

[英]@Autowired : No qualifying bean of type available SpringBoot application

我在库中定义了一个接口com.myapp.org.UsageRateLimiter

public interface UsageRateLimiter {
  
  boolean tryAndConsume(String userId, String key, Long units);
}

我有一个具体的 class SlidingWindowRateLimiter

@Component("slidingWindowRateLimiter")
public class SlidingWindowRateLimiter implements UsageRateLimiter {
  private final RateLimitingRedisProperties rateLimitingRedisProperties;

  public SlidingWindowRateLimiter(RateLimitingRedisProperties rateLimitingRedisProperties) {
    this.rateLimitingRedisProperties = rateLimitingRedisProperties;
  }

  @Override
  public boolean tryAndConsume(String userId, String key, Long units) {
    
    return true;
}

另一个 class com.myapp.org.RateLimitDriver引用了UsageRateLimiter类型的 object:

public class RateLimiterDriver {
  UsageRateLimiter rateLimiter;

  @Autowired
  RateLimiterDriver(UsageRateLimiter usageRateLimiter) {
    rateLimiter = usageRateLimiter;
  }

  public Decision getDecision(
      String userId, String key, BiFunction<String, String, Long> consumptionObject) {
    return rateLimiter.tryAndConsume(
            userId, key, consumptionObject.apply(userId, key))
        ? true
        : false;
  }
}

将会有UsageRateLimiter的其他实现以及不同的组件名称

现在在我的 controller class 中我需要实例化RateLimiterDriver

@RestController
@RequestMapping("/myApp/v1")
@Slf4j
public class MyappController implements MyappApi {

  @Autowired
  @Qualifier("slidingWindowRateLimiter")
  private RateLimiterDriver rateLimiterDriver;

  @Override
  public ResponseEntity<MyappResponse> createMyAppInstance(
      @RequestBody MyappPayload myAppPayload) {
    if (rateLimiterDriver.getDecision(userId, "create_my_app") == Decision.ALLOW) {
      return new ResponseEntity<>(HttpStatus.TOO_MANY_REQUESTS);
    }
  }
}

在部署期间,我收到以下错误:

No qualifying bean of type 'com.myapp.org.RateLimiterDriver' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true), @org.springframework.beans.factory.annotation.Qualifier(value="slidingWindowRateLimiter")}

更新:据我所知,限定符(“slidingWindowRateLimiter”)不应在 RateLimitDriver class 上,而应在 UsageLimiter class 上。

如何使用 spring 注释从 MyAppController 传递正确的 UsageLimiter 实现? 抱歉,我是 spring 引导的新手,因此寻求帮助。

最后,我能够使用以下事实提出一个解决方案Spring 提供了将所有作为接口具体实现的 Bean 收集到 Map 中的能力

我将我的RateLimiterDriver class 修改为:

@Component
public class RateLimiterDriver {
  @Value("${com.myapp.org.ratelimiter.type}")
  private String rateLimiterType;

  Map<String, UsageRateLimiter> rateLimiterTypeImplMap;

  @Autowired
  RateLimiterDriver(Map<String, UsageRateLimiter> rateLimiterTypeMap) {
    rateLimiterTypeImplMap = rateLimiterTypeMap;
  }

  public Decision getDecision(
      String userId, String key, BiFunction<String, String, Long> consumptionObject) {
    return rateLimiterTypeImplMap
            .get(rateLimiterType)
            .tryAndConsume(userId, key, consumptionObject.apply(userId, key))
        ? Decision.ALLOW
        : Decision.DROP;
  }
}

在我的MyAppController中,我可以简单地做

@Autowired RateLimiterDriver

并在属性文件中提供 bean 名称:

com.myapp.org.ratelimiter.type=slidingWindowRateLimiter

瞧。 现在一切正常。 感谢@timeofeevle 的建议。

参考文章:

Spring 中的动态自动装配

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM