-1

I'm totally new to the concept of spring boot IoC, and @Bean

Let's say this code is implemented

@SpringBootApplication
public class MyApplication{
    @Bean
    public WebClient rest(ReactiveClientRegistrationRepository clients,
                          ServerOAuth2AuthorizedClientRepository authz) {

You see here, there is only 1 class that implements the interface ReactiveClientRegistrationRepository so my correct guess is if there's only one class that implements it, then that would be automatically autowired to the clients parameter

public final class InMemoryReactiveClientRegistrationRepository
        implements ReactiveClientRegistrationRepository, Iterable<ClientRegistration> {

On the other hand, ServerOAuth2AuthorizedClientRepository is implemented by 3 different classes namely

public final class AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository
        implements ServerOAuth2AuthorizedClientRepository {


public class UnAuthenticatedServerOAuth2AuthorizedClientRepository implements ServerOAuth2AuthorizedClientRepository {



public final class WebSessionServerOAuth2AuthorizedClientRepository
        implements ServerOAuth2AuthorizedClientRepository {

Upon debugging, the class that get picked up is AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository

How does spring boot framework knows which is which? I think there would be bean conflicts such as in this question Spring boot autowiring an interface with multiple implementations

Minah
  • 81
  • 1
  • 9

1 Answers1

0

The reason why ServerOAuth2AuthroizedClientRepostiry is an instance of AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository is because Spring will by default look for a bean that resolves to type ServerOAuth2AuthroizedClientRepiository but if one does not exist, a new AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository object will be created.

If you want to override this you can create a new Bean with the type of your choice.

@Bean
ServerOAuth2AuthroizedClientRepostiry repository() {
    return new WebSessionServerOAuth2AuthorizedClientRepository(...);
}
Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140
Jason
  • 5,154
  • 2
  • 12
  • 22
  • But there is no qualifier used to choose which one. This is a standard code I got from the docs. – Minah Apr 16 '20 at 15:54
  • My apologies, I thought those were custom implementations, i'll edit my post. – Jason Apr 16 '20 at 15:55
  • If they're not beans, what/how is Spring injecting them into the `rest` `@Bean` annotated factory method? – Savior Apr 16 '20 at 16:09
  • Oh wow yeah it does look like they look for a bean first before falling back on class members. – Jason Apr 16 '20 at 16:13
  • Docs for what? The OP has a `MyApplication` configuration class with a `@Bean` factory method. They claim that method receives a `AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository` object. Where is that object coming from if it's not a bean? – Savior Apr 16 '20 at 16:13
  • It is coming from ServerHttpSecurity#getAuthorizedClientService() and a new AuthenticatedPricincipalServerOAuth2AuthorizedCLeintRepository object is being created from it. – Jason Apr 16 '20 at 16:14
  • I saw this part getBeanOrNull(ServerOAuth2AuthorizedClientRepository.class); So technically, it is set up as a Bean. If I want to choose WebSessionServerOAuth2AuthorizedClientRepository instead of AuthenticatedPrincipalServerOAuth2AuthorizedClientRepository, how would I do it in my application context? – Minah Apr 16 '20 at 16:19
  • I'll create another answer, one second. – Jason Apr 16 '20 at 16:21