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
}
Предположим, мы хотим внедрить список объектов типа Vehicle
в некоторый класс-обработчик:
@Autowired
private List<Vehicle> vehicles;
Spring автоматически подключит все bean- компоненты экземпляра Vehicle
в этот список. Неважно, как мы создаем экземпляры этих bean-компонентов с помощью конфигурации Java или XML.
Мы также можем использовать квалификаторы, чтобы получить только определенные bean-компоненты типа Vehicle
. Затем мы создаем @CarQualifier
и аннотируем его @Qualifier
:
@Target({
ElementType.FIELD,
ElementType.METHOD,
ElementType.TYPE,
ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface CarQualifier {
}
Теперь мы можем использовать эту аннотацию в нашем списке, чтобы получить только некоторые определенные транспортные средства
:
@Autowired
@CarQualifier
private List<Vehicle> vehicles;
В этом случае мы можем создать несколько bean-компонентов Vehicle
, но Spring вставит в список выше только те из них, у которых есть @CarQualifier :
public class CustomConfiguration {
@Bean
@CarQualifier
public Car getMercedes() {
return new Car("E280", "Mercedes", "Diesel");
}
}
3. Автомонтирование дженериков в Spring 4.0.
Предположим, у нас есть еще один подкласс Vehicle с именем
Motorcycle
:
public class Motorcycle extends Vehicle {
private boolean twoWheeler;
//... getters, setters etc
}
Теперь, если мы хотим внедрить в наш список только bean -компоненты Car , а не
Motorcycle
, мы можем сделать это, используя конкретный подкласс в качестве параметра типа:
@Autowired
private List<Car> vehicles;
Spring позволяет нам использовать универсальный тип в качестве квалификатора без необходимости явной аннотации, начиная с версии 4.0.
До Spring 4.0 приведенный выше код не работал с bean-компонентами нескольких подклассов Vehicle
.
Без явных квалификаторов мы получили бы NonUniqueBeanDefinitionException
.
4. Разрешаемый тип
Функция автоматического связывания дженериков работает с помощью класса ResolvableType
за кулисами.
Он был представлен в Spring 4.0 для инкапсуляции типа Java и обработки доступа к супертипам, интерфейсам, универсальным параметрам и, наконец, разрешению класса:
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);
Вывод приведенного выше кода покажет соответствующие простые и универсальные типы:
java.util.List<com.example.model.Vehicle>
com.example.model.Vehicle
class com.example.model.Vehicle
5. Вывод
Внедрение универсальных типов — это мощная функция, которая избавляет разработчика от необходимости назначать явные квалификаторы, делая код чище и намного понятнее.
Как всегда, код можно найти на GitHub .