I have a spring boot app with some repositories (i.e. InMemory, Database) that implement a common interface (IRepository), and a factory for accessing them as below.
public class SomeRepositoryFactory {
public IRepository getRepository(String repoType) {
if (repoType == "Database") {
return new DatabaseRepository();
} else if (repoType == "InMemory") {
return new InMemoryRepository();
}
return null;
}
}
There is also a service class that has a repository as a dependency
public class SomeService {
private IRepository repository;
public SomeService (IRepository repository) {
this.repository = repository;
}
}
I managed to wire them fine manually with the following configuration
@Configuration
public class MyConfig {
@Bean
public SomeRepositoryFactory someRepositoryFactory() {
return new SomeRepositoryFactory();
}
@Bean
public IRepository someRepository() {
return someRepositoryFactory().getRepository("InMemory");
}
@Bean
public SomeService someService() {
return new SomeService(someRepository());
}
}
However, I'd like to try use autowiring to accomplish this. In particular, I'm not sure how to inject the service class with a repository that is retrieved from the factory. Ideally I'd like to have some annotation like this
@Component
@inject with SomeRepositoryFactory.getRepository.("InMemory")
public class SomeService {
private IRepository repository;
public SomeService (IRepository repository) {
this.repository = repository;
}
}
CodePudding user response:
If you have only one bean with an implementation for an interface you simply have inject it like you would any other managed instance. You can use constructor injection, @Autowire
, setter injection, etc.
This should simply work:
@Component
public class SomeService {
private IRepository repository;
// Constructor injection here, should find the bean from someRepository configuration method
public SomeService (IRepository repository) {
this.repository = repository;
}
}
In case you have multiple implementation for the same interface, you could annotate it the injection with @Qualifier
:
@Component
public class SomeService {
private IRepository repository;
public SomeService (@Qualifier("someRepository") IRepository repository) {
this.repository = repository;
}
}