Автор оригинала: Attila Fejér.
1. Обзор
Мы можем использовать возможности Spring DI engine, используя аннотации в org.springframework.beans.factory.аннотации и org.springframework.контекст.аннотации пакеты.
Мы часто называем их “аннотациями Spring core”, и мы рассмотрим их в этом руководстве.
2. Аннотации, связанные с DI
2.1. @Autowired
Мы можем использовать @Autowired для пометки зависимости, которую Spring собирается разрешить и внедрить . Мы можем использовать эту аннотацию с конструктором, настройщиком или введением поля.
Инъекция конструктора:
class Car { Engine engine; @Autowired Car(Engine engine) { this.engine = engine; } }
Инъекция сеттера:
class Car { Engine engine; @Autowired void setEngine(Engine engine) { this.engine = engine; } }
Полевая инъекция:
class Car { @Autowired Engine engine; }
@Autowired имеет логический аргумент с именем требуется со значением по умолчанию true . Он настраивает поведение пружины, когда она не находит подходящего боба для подключения. Когда true , создается исключение, в противном случае ничего не подключается.
Обратите внимание, что если мы используем инъекцию конструктора, все аргументы конструктора являются обязательными.
Начиная с версии 4.3, нам не нужно явно аннотировать конструкторы с помощью @Autowired , если мы не объявим по крайней мере два конструктора.
Для получения более подробной информации посетите наши статьи о @Autowired и внедрении конструктора .
2.2. @Bean
@Bean отмечает фабричный метод, который создает экземпляр пружинного компонента:
@Bean Engine engine() { return new Engine(); }
Spring вызывает эти методы , когда требуется новый экземпляр возвращаемого типа.
Полученный компонент имеет то же имя, что и заводской метод. Если мы хотим назвать его по-другому, мы можем сделать это с помощью имени или значения аргументов этой аннотации (аргумент значение является псевдонимом для аргумента имя ):
@Bean("engine") Engine getEngine() { return new Engine(); }
Обратите внимание, что все методы, аннотированные @Bean , должны быть в классах @Configuration .
2.3. @Квалификатор
Мы используем @Квалификатор вместе с @Autowired для предоставления идентификатора компонента или имени компонента , которые мы хотим использовать в неоднозначных ситуациях.
Например, следующие два компонента реализуют один и тот же интерфейс:
class Bike implements Vehicle {} class Car implements Vehicle {}
Если Spring нужно ввести Транспортное средство компонент, он заканчивается несколькими соответствующими определениями. В таких случаях мы можем явно указать имя компонента, используя аннотацию @Квалификатор .
Использование инъекции конструктора:
@Autowired Biker(@Qualifier("bike") Vehicle vehicle) { this.vehicle = vehicle; }
Использование инъекции сеттера:
@Autowired void setVehicle(@Qualifier("bike") Vehicle vehicle) { this.vehicle = vehicle; }
Альтернативно:
@Autowired @Qualifier("bike") void setVehicle(Vehicle vehicle) { this.vehicle = vehicle; }
Использование полевой инъекции:
@Autowired @Qualifier("bike") Vehicle vehicle;
Для более подробного описания, пожалуйста, прочтите эту статью .
2.4. @Требуется
@Требуется о методах настройки для обозначения зависимостей, которые мы хотим заполнить с помощью XML:
@Required void setColor(String color) { this.color = color; }
В противном случае будет выдано исключение BeanInitializationException .
2.5. @Значение
Мы можем использовать @Value для ввода значений свойств в компоненты. Он совместим с конструктором, настройщиком и внедрением в поле.
Инъекция конструктора:
Engine(@Value("8") int cylinderCount) { this.cylinderCount = cylinderCount; }
Инъекция сеттера:
@Autowired void setCylinderCount(@Value("8") int cylinderCount) { this.cylinderCount = cylinderCount; }
Альтернативно:
@Value("8") void setCylinderCount(int cylinderCount) { this.cylinderCount = cylinderCount; }
Полевая инъекция:
@Value("8") int cylinderCount;
Конечно, вводить статические значения бесполезно. Поэтому мы можем использовать строки-заполнители в @Value для передачи значений , определенных во внешних источниках , например, в файлах .properties или|/. yaml .
Давайте предположим, что .свойства файл:
engine.fuelType=petrol
Мы можем ввести значение engine.тип топлива со следующим:
@Value("${engine.fuelType}") String fuelType;
Мы можем использовать @Value даже с помощью заклинания. Более продвинутые примеры можно найти в нашей статье о @Value .
2.6. @dependsOn
Мы можем использовать эту аннотацию, чтобы заставить Spring инициализировать другие компоненты перед аннотированным . Обычно это поведение выполняется автоматически на основе явных зависимостей между компонентами.
Нам нужна эта аннотация только в том случае , если зависимости неявны , например, загрузка драйвера JDBC или инициализация статической переменной.
Мы можем использовать @Зависит от зависимого класса, указывающего имена компонентов зависимости. Для аргумента value аннотации требуется массив, содержащий имена компонентов зависимостей:
@DependsOn("engine") class Car implements Vehicle {}
В качестве альтернативы, если мы определяем компонент с аннотацией @Bean , фабричный метод должен быть аннотирован с помощью @dependsOn :
@Bean @DependsOn("fuel") Engine engine() { return new Engine(); }
2.7. @Ленивый
Мы используем @Lazy, когда хотим лениво инициализировать наш компонент. По умолчанию Spring охотно создает все одноэлементные компоненты при запуске/загрузке контекста приложения.
Однако бывают случаи, когда нам нужно создать компонент, когда мы запрашиваем его, а не при запуске приложения .
Эта аннотация ведет себя по-разному в зависимости от того, где мы ее точно размещаем. Мы можем надеть его:
- @Bean аннотированный метод фабрики бобов, чтобы задержать вызов метода (следовательно, создание боба)
- @ Конфигурация класс и все содержащиеся @Bean методы будут затронуты
- @Компонент класс, который не является @Конфигурацией классом, этот компонент будет лениво инициализирован
- /| @Autowired конструктор, установщик или поле для ленивой загрузки самой зависимости (через прокси)
Эта аннотация имеет аргумент с именем значение со значением по умолчанию true . Полезно переопределить поведение по умолчанию.
Например, пометить компоненты, которые будут загружаться с нетерпением, когда глобальная настройка неактивна, или настроить конкретные @Bean методы для быстрой загрузки в @Конфигурации классе, помеченном @Lazy :
@Configuration @Lazy class VehicleFactoryConfig { @Bean @Lazy(false) Engine engine() { return new Engine(); } }
Для дальнейшего чтения, пожалуйста, посетите эту статью .
2.8. Поиск @
Метод с аннотацией @Lookup указывает Spring возвращать экземпляр возвращаемого типа метода при его вызове.
Подробную информацию об аннотации можно найти в этой статье .
2.9. @Первичный
Иногда нам нужно определить несколько компонентов одного и того же типа. В этих случаях инъекция будет неудачной, потому что Spring понятия не имеет, какой боб нам нужен.
Мы уже видели возможность справиться с этим сценарием: пометить все точки подключения с помощью @квалификатора и указать имя требуемого компонента.
Однако в большинстве случаев нам нужен конкретный компонент, и редко другие. Мы можем использовать @Primary для упрощения этого случая: если мы пометим наиболее часто используемый компонент @Primary , он будет выбран в неквалифицированных точках инъекции:
@Component @Primary class Car implements Vehicle {} @Component class Bike implements Vehicle {} @Component class Driver { @Autowired Vehicle vehicle; } @Component class Biker { @Autowired @Qualifier("bike") Vehicle vehicle; }
В предыдущем примере Автомобиль является основным транспортным средством. Поэтому в классе Driver Spring вводит Car компонент. Конечно, в Байкере бобе значение поля транспортное средство будет Велосипед объект, потому что он квалифицирован.
2.10. @Область применения
Мы используем @Область действия для определения области действия @Компонента класса или @компонента определения . Это может быть либо синглтон, прототип, запрос, сеанс, глобальная сессия или какая-либо пользовательская область.
Например:
@Component @Scope("prototype") class Engine {}
3. Аннотации Конфигурации контекста
Мы можем настроить контекст приложения с помощью аннотаций, описанных в этом разделе.
3.1. @Профиль
Если мы хотим , чтобы Spring использовал @Компонент класс или @Компонент метод только тогда, когда активен определенный профиль , мы можем пометить его @Профиль . Мы можем настроить имя профиля с помощью значения аргумента аннотации:
@Component @Profile("sportDay") class Bike implements Vehicle {}
Вы можете прочитать больше о профилях в этой статье .
3.2. @Импорт
Мы можем использовать конкретные @Конфигурации классы без сканирования компонентов с этой аннотацией. Мы можем предоставить этим классам @Import ‘подстановку значение аргумент:
@Import(VehiclePartSupplier.class) class VehicleFactoryConfig {}
3.3. @ImportResource
Мы можем импортировать конфигурации XML с помощью этой аннотации. Мы можем указать расположение XML-файла с аргументом locations или с его псевдонимом, аргументом value :
@Configuration @ImportResource("classpath:/annotations.xml") class VehicleFactoryConfig {}
3.4. @PropertySource
С помощью этой аннотации мы можем определить файлы свойств для настроек приложения :
@Configuration @PropertySource("classpath:/annotations.properties") class VehicleFactoryConfig {}
@PropertySource использует функцию повторяющихся аннотаций Java 8, что означает, что мы можем отмечать класс с помощью нее несколько раз:
@Configuration @PropertySource("classpath:/annotations.properties") @PropertySource("classpath:/vehicle-factory.properties") class VehicleFactoryConfig {}
3.5. @PropertySources
Мы можем использовать эту аннотацию для указания нескольких @PropertySource конфигураций:
@Configuration @PropertySources({ @PropertySource("classpath:/annotations.properties"), @PropertySource("classpath:/vehicle-factory.properties") }) class VehicleFactoryConfig {}
Обратите внимание, что начиная с Java 8 мы можем добиться того же с помощью функции повторяющихся аннотаций, как описано выше.
4. Заключение
В этой статье мы рассмотрели обзор наиболее распространенных аннотаций Spring core. Мы рассмотрели, как настроить проводку компонентов и контекст приложения, а также как пометить классы для сканирования компонентов.
Как обычно, примеры доступны на GitHub .