Reputation: 5018
I have a small spinet of Java code:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import me.cimply.ask.odata.repository.*;
@Component
public class Runner implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(Runner.class);
@Autowired
private IconRepository iconRepository;
@Autowired
private UserRepository userRepository;
@Override
public void run(String... args) throws Exception {
this.fillRepository(iconRepository);
this.fillRepository(userRepository);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void fillRepository(BaseRepository repository) {
// Code
}
}
I want to make this code as generic as possible.
I would like to extract the names of all the interfaces inside the me.cimply.ask.odata.repository
package and generate the instances of them in a loop in the run
method or in the constructor of the class and invoke the fillRepository
method for them.
In the other word, I would like to only add new interfaces inside the me.cimply.ask.odata.repository
package and the above code is run for them too, without adding any new line of code each time here. Something like this pseudocode:
import me.cimply.ask.odata.repository.*;
@Component
public class Runner implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(Runner.class);
private BaseRepository repositories[];
public Runner(){
for(InterfaceX in me.cimply.ask.odata.repository.*){
repositories.push(new Autowired instance of InterfaceX);
}
}
@Override
public void run(String... args) throws Exception {
for(repo in repositories)
this.fillRepository(repo);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void fillRepository(BaseRepository repository) {
// Code
}
}
Please note BaseRepository
is an interface in the me.cimply.ask.odata.repository
package that all other interfaces implement that!
I searched a lot, and it seems the Autowired
must be defined as a class property, anyway maybe someone know a technique to implement this idea!
Upvotes: 0
Views: 127
Reputation: 428
If every of your repositories implement BaseRepository
, then you can do that:
import me.cimply.ask.odata.repository.*;
@Component
public class Runner implements CommandLineRunner {
private List<BaseRepository> repositories;
@Autowired
public Runner(List<BaseRepository> repositories){
this.repositories = repositories;
}
@Override
public void run(String... args) throws Exception {
for(BaseRepository repo : repositories)
this.fillRepository(repo);
}
@SuppressWarnings({ "rawtypes", "unchecked" })
private void fillRepository(BaseRepository repository) {
// Code
}
}
Upvotes: 1
Reputation: 265928
If you have several beans implementing a common interface, define a dependency on the list of interfaces and Spring will give you all the available implementations:
@Component
public class Runner {
private final List<Interface> beans;
@Autowired
public Runner(final List<Interface> beans) {
this.beans = beans;
// beans will contain Bean1, Bean2, Bean3
}
}
public interface Interface {}
@Component
public class Bean1 implements Interface {}
@Component
public class Bean2 implements Interface {}
@Component
public class Bean3 implements Interface {}
Upvotes: 1