«1. Обзор
В этом руководстве мы увидим, как внедрять bean-компоненты Spring по общим параметрам.
2. Универсальные автомонтирования в Spring 3.2.
Spring поддерживает внедрение универсальных типов, начиная с версии 3.2.
Предположим, у нас есть абстрактный класс Vehicle и его конкретный подкласс Car:
public abstract class Vehicle {
private String name;
private String manufacturer;
// ... getters, setters etc
}
public class Car extends Vehicle {
private String engineType;
// ... getters, setters etc
}
@Autowired
private List<Vehicle> vehicles;
Предположим, мы хотим внедрить список объектов типа Vehicle в некоторый класс-обработчик: ~~ ~
Spring автоматически подключит все bean-компоненты экземпляров Vehicle в этот список. Неважно, как мы создаем экземпляры этих bean-компонентов с помощью конфигурации Java или XML.
@Target({
ElementType.FIELD,
ElementType.METHOD,
ElementType.TYPE,
ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CarQualifier {
}
Мы также можем использовать квалификаторы, чтобы получить только определенные bean-компоненты типа Vehicle. Затем мы создаем @CarQualifier и аннотируем его с помощью @Qualifier:
@Autowired
@CarQualifier
private List<Vehicle> vehicles;
Теперь мы можем использовать эту аннотацию в нашем списке, чтобы получить только некоторые определенные автомобили:
public class CustomConfiguration {
@Bean
@CarQualifier
public Car getMercedes() {
return new Car("E280", "Mercedes", "Diesel");
}
}
В этом случае мы можем создать несколько компонентов Vehicle но Spring вставит в список выше только тех, у кого есть @CarQualifier:
3. Autowiring Generics в Spring 4.0.
public class Motorcycle extends Vehicle {
private boolean twoWheeler;
//... getters, setters etc
}
Предположим, у нас есть еще один подкласс Vehicle с именем Motorcycle:
@Autowired
private List<Car> vehicles;
Теперь, если мы хотим внедрить в наш список только bean-компоненты Car, а не Motorcycle, мы можем сделать это с помощью специального подкласса в качестве параметра типа:
Начиная с версии 4.0 Spring позволяет нам использовать общий тип в качестве квалификатора без необходимости явной аннотации.
До Spring 4.0 приведенный выше код не работал с bean-компонентами нескольких подклассов Vehicle. Без явных квалификаторов мы получили бы исключение NonUniqueBeanDefinitionException.
4. ResolvableType
Функция автоматического связывания дженериков работает с помощью класса ResolvableType за кулисами.
ResolvableType vehiclesType = ResolvableType.forField(getClass().getDeclaredField("vehicles"));
System.out.println(vehiclesType);
ResolvableType type = vehiclesType.getGeneric();
System.out.println(type);
Class<?> aClass = type.resolve();
System.out.println(aClass);
Он был представлен в Spring 4.0 для инкапсуляции типа Java и обработки доступа к супертипам, интерфейсам, универсальным параметрам и, наконец, разрешению в класс:
java.util.List<com.example.model.Vehicle>
com.example.model.Vehicle
class com.example.model.Vehicle
Вывод приведенного выше кода будет отображать соответствующие простые и универсальные типы. :
5. Заключение
Внедрение универсальных типов — это мощная функция, которая избавляет разработчика от необходимости назначать явные квалификаторы, делая код чище и намного понятнее.