Автор оригинала: 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 .