简体   繁体   中英

Spring-Boot: Dependency Injection depending on the configuration (and using interfaces)

I have the following question regarding the structure of my application architecture. Assume my application consists of the following components

First of all a @ConfigurationProperties , which initializes my needed properties (here only a type to select a provider). In addition, a bean of the type " Provider " is to be registered at this point depending on the specified type. This type is implemented as an interface and has two concrete implementations in this example ( ProviderImplA & ProviderImplB ).

@Configuration
@Profile("provider")
@ConfigurationProperties(prefix = "provider")
@ConditionalOnProperty(prefix = "provider", name = ["type"])
class ProviderConfiguration {
    lateinit var type: String

    @Bean(name = ["provider"])
    fun provider(): Provider {
        return when (type) {
            "providerA" -> ProviderImplA()
            "providerB" -> ProviderImplB()
        }

    }

}

Next, only the two concrete implementation of the interface.

class ProviderImplA: Provider {

    @Autowired
    lateinit var serviceA: ServiceA

}
class ProviderImplB: Provider {

    @Autowired
    lateinit var serviceA: ServiceA
    @Autowired
    lateinit var serviceB: ServiceB
    @Autowired
    lateinit var serviceC: ServiceC

}

And last but not least the interface itself.

interface Provider{
    fun doSomething()
}

Now to the actual problem or better my question:
Because my concrete implementations (ProviderImplA and ProviderImplB) are no valid defined beans (missing annotation eg @Component), but they have to use their own @Service components, it is not possible to use @Autworie at this point. I would like to avoid different profiles/configurations if possible, therefore the initialization by property. How can I still use the individual @Service's within my implementations and still create the provider beans manually, depending on the configuration (only one provider exists at runtime)? Maybe you have other suggestions or improvements?

When instantiating objects directly, spring cannot control its life cycle, so you must create an @Bean for each 'Provider'

@Bean(name = ["providerA"])
@Lazy
fun providerA(): Provider {
  return ProviderImplA()
}

@Bean(name = ["providerB"])
@Lazy
fun providerB(): Provider {
   return ProviderImplB()
}

IdentityProviderConfiguration class

IdentityProviderConfiguration {
  var context: ApplicationContext
  ...

  fun provider(): Provider {
    return when (type) {
     "providerA" -> context.getBean("providerA")
     "providerB" -> context.getBean("providerB")
    }
  }

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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