How to use Spring to autowire list types? How to autowired all subclasses of a parent class, or all implementations of an interface.
Let’s see an example - we have three pets that we’d like to register them on the public animal registry.
public abstract class Animal { ... } |
@Component
public class MyDog extends Animal { ... } |
@Component
public class MyCat extends Animal { ... } |
@Component
public class MyBird extends Animal { ... } |
The question is - how to register all my animals?
@Component
public class AnimalRegistry {
private Map<String, Animal> registry;
// How to register all my animals to the registry?
} |
Naive Approach
@Component
public class AnimalRegistry {
private Registry<Animal> registry;
/**
* This is naive because if you have more animals,
* you have to specify them explicitly here
*/
@Autowired
public AnimalRegistry (MyDog dog, MyCat cat, MyBird bird){
registry.register(dog);
registry.register(cat);
registry.register(bird);
}
} |
Have Spring Autowire All Subclass
@Component
public class AnimalRegistry {
private Registry<Animal> registry;
/**
* The problem with this approach is that
* if you don't have any animals, there's no bean to be autowired here,
* and Spring will report bean initialization error
*/
@Autowired
public AnimalRegistry (List<Animal> myAnimals){
if(myAnimals != null && !myAnimals.isEmpty()) {
myAnimals.forEach(a -> registry.register(a));
}
}
} |
Better Usage of @Autowired
@Component
public class AnimalRegistry {
private Registry<Animal> registry;
@Autowired(required = false)
List<Animal> myAnimals;
/**
* This ensures that Spring can still successfully run
* even when there's no bean to be autowired to 'myAnimals'
*/
@PostConstruct
public void init() {
if(myAnimals != null && !myAnimals.isEmpty()) {
myAnimals.forEach(a -> registry.register(a));
}
}
} |
This tip should work well w.r.t interfaces
public inteface Provider { ... } |
@Component
public class DogProvider implements Provider { ... } |
@Component
public class CatProvider implements Provider { ... } |
@Component
public class BirdProvider implements Provider { ... } |
@Component
public class ProviderRegistry {
private Registry<Provider> registry;
@Autowired(required = false)
List<Provider> providers;
@PostConstruct
public void init() {
if(providers != null && !providers.isEmpty()) {
providers.forEach(a -> registry.register(a));
}
}
}
来源:oschina
链接:https://my.oschina.net/ciet/blog/3162086