java - 如何在 Spring 中为 Autowiring 指定默认 bean?

标签 java spring dependency-injection autowired

我正在编写库和使用该库的服务。我想要一个 UsernameProvider 服务,它负责提取登录用户的用户名。我使用图书馆本身的服务:

class AuditService {
  @Autowired
  UsernameProvider usernameProvider;

  void logChange() {
    String username = usernameProvider.getUsername();
    ...
  }
}

我想要一个 UsernameProvider 接口(interface)的默认实现,它从 JWT 的主题声明中提取用户名。但是,在依赖库的服务中,我想使用基本身份验证,因此我将创建一个覆盖 getUsername()BasicAuthUsernameProvider

当有多个相同类型的 Autowiring 候选者(库中的 DefaultUsernameProvider 和服务中的 BasicAuthUsernameProvider)时,我自然会出错,所以我会将服务中的 bean 标记为 @Primary。但我不想让库客户端指定主 bean,而是标记为默认值。

DefaultUsernameProvider 上添加 @Order(value = Ordered.LOWEST_PRECEDENCE) 无效。

在库的配置类中添加 @ConditionalOnMissingBean 也不起作用。

编辑: 事实证明,在 UsernameProvider 实现类上添加 @Component 会导致 @ConditionalOnMissingBean 无用,因为Spring Boot 尝试 Autowiring 每个注释为组件的类,因此抛出“Multiple beans of type found” 异常。

最佳答案

您可以使用 @ConditionalOnMissingBean 注释实例化 bean 的方法。这意味着只有当没有其他 UserProvider 被声明为 bean 时,该方法才会用于实例化您的 bean。

在下面的示例中,您不得将类 DefaultUserProvider 注释为 ComponentService 或任何其他 bean 注释。

@Configuration
public class UserConfiguration {

  @Bean
  @ConditionalOnMissingBean
  public UserProvider provideUser() {

    return new DefaultUserProvider();
  }
}

关于java - 如何在 Spring 中为 Autowiring 指定默认 bean?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53615708/

相关文章:

objective-c - 你能在 Objective-C 中完成某种形式的依赖注入(inject)吗?

java - 如何在应用程序启动时启动后台线程

java - DFA 字符串验证

java - InstantiationError : org. quartz.JobDetail 使 tomcat9 在 linux 中启动失败但在 windows 中正常

spring - 使用注释按名称 Autowiring spring bean

java - 注入(inject)非 bean 属性的最佳实践

java - Bean 被初始化但注入(inject)抛出 npe

java - 如何根据显着光值使振动不同?

java - 使用 JNI 调用 Java 方法时的 "Method Signature"参数是什么?

java - JDBC 模板表锁定问题