簡體   English   中英

如何在Spring中指定用於自動裝配的默認bean?

[英]How to specify a default bean for autowiring in Spring?

我正在編寫使用此庫的庫和服務。 我想要一個UsernameProvider服務,它負責提取登錄用戶的用戶名。 我在庫中使用服務:

class AuditService {
  @Autowired
  UsernameProvider usernameProvider;

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

我希望有一個UsernameProvider接口的默認實現,它從JWT的主題聲明中提取用戶名。 但是,在依賴於庫的服務中,我想使用基本身份驗證,因此我創建了一個覆蓋getUsername()BasicAuthUsernameProvider

當有多個相同類型的autowire候選者( DefaultUsernameProvider中的DefaultUsernameProvider和服務中的BasicAuthUsernameProvider )時,我自然會收到錯誤,因此我必須將服務中的bean標記為@Primary 但我不希望庫客戶端指定主bean,而是標記默認值。

添加@Order(value = Ordered.LOWEST_PRECEDENCE)DefaultUsernameProvider沒有工作。

@ConditionalOnMissingBean中的Configuration類中添加@ConditionalOnMissingBean也不起作用。

編輯:結果,在UsernameProvider實現類上添加@Component使得@ConditionalOnMissingBean無用,因為Spring Boot試圖將每個注釋為Component的類自動裝配,因此拋出“找到類型的多個bean”異常。

你沒有發布DefaultUsernameProvider的代碼,但我猜它注釋為@Component因此它是自動連線的候選者,與BasicAuthUsernameProvider相同。 如果要控制使用其中的哪一個,而不是將它們都標記為組件,請添加@Configuration類,並在那里創建UsernameProvider bean:

@Configuration
public class ProviderConfig {
    @Bean
    public UsernameProvider() {
         return new BasicAuthUsernameProvider();
    }
}

然后,這個bean將在需要的任何地方自動連接

您可以使用@ConditionalOnMissingBean注釋實例化bean的方法。 這意味着只有在沒有其他UserProvider被聲明為bean時,該方法才會用於實例化bean。

在下面的示例中,您不能將類DefaultUserProvider注釋為ComponentService或任何其他bean注釋。

@Configuration
public class UserConfiguration {

  @Bean
  @ConditionalOnMissingBean
  public UserProvider provideUser() {

    return new DefaultUserProvider();
  }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM