Рубрики
Без рубрики

Руководство по весне @Autowired

Руководство по наиболее распространенному использованию аннотаций и квалификаторов Spring @Autowired

Автор оригинала: baeldung.

1. Обзор

Начиная с Spring 2.5, в фреймворке были введены управляемые аннотациями Инъекции зависимостей . Основная аннотация этой функции – @Autowired . Это позволяет Spring разрешать и вводить сотрудничающие бобы в наш боб.

Дальнейшее чтение:

Сканирование пружинных Компонентов

Введение в инверсию управления и внедрение зависимостей с помощью пружины

В этом уроке мы сначала рассмотрим, как включить автоматическое подключение и различные | способы автоматического подключения компонентов. Позже мы поговорим о разрешении конфликтов компонентов с использованием @квалификатора аннотации, , а также о возможных сценариях исключений.

2. Включение аннотаций @Autowired

Платформа Spring позволяет автоматически внедрять зависимости. Другими словами, объявив все зависимости компонентов в файле конфигурации Spring, контейнер Spring может автоматически устанавливать связи между сотрудничающими компонентами . Это называется Автопроводка Spring bean .

Чтобы использовать конфигурацию на основе Java в нашем приложении, давайте включим инъекцию на основе аннотаций для загрузки нашей конфигурации Spring:

@Configuration
@ComponentScan("com.baeldung.autowire.sample")
public class AppConfig {}

В качестве альтернативы, аннотация <контекст:аннотация-конфигурация> в основном используется для активации аннотаций внедрения зависимостей в XML-файлах Spring.

Кроме того, Spring Boot вводит @SpringBootApplication аннотацию . Эта единственная аннотация эквивалентна использованию @Configuration , @EnableAutoConfiguration и @ComponentScan .

Давайте использовать эту аннотацию в основном классе приложения:

@SpringBootApplication
class VehicleFactoryApplication {
    public static void main(String[] args) {
        SpringApplication.run(VehicleFactoryApplication.class, args);
    }
}

В результате, когда мы запускаем это приложение Spring Boot, оно автоматически сканирует компоненты в текущем пакете и его подпакетах . Таким образом, он зарегистрирует их в контексте приложения Spring и позволит нам вводить компоненты с помощью @Autowired .

3. Использование @Autowired

После включения внедрения аннотаций мы можем использовать автоматическое подключение к свойствам, установщикам и конструкторам .

3.1. @Автоматически подключается к свойствам

Давайте посмотрим, как мы можем аннотировать свойство с помощью @Autowired . Это устраняет необходимость в геттерах и сеттерах.

Во-первых, давайте определим FooFormatter bean:

@Component("fooFormatter")
public class FooFormatter {
    public String format() {
        return "foo";
    }
}

Затем мы введем эту фасоль в Службу питания фасоль, используя @Autowired об определении поля:

@Component
public class FooService {  
    @Autowired
    private FooFormatter fooFormatter;
}

В результате Spring вводит FooFormatter при создании Службы питания .

3.2. @Автоматическое подключение к сеттерам

Теперь давайте попробуем добавить @Autowired аннотация метода настройки.

В следующем примере метод setter вызывается с экземпляром FooFormatter при создании Службы питания :

public class FooService {
    private FooFormatter fooFormatter;
    @Autowired
    public void setFooFormatter(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

3.3. @Автоматически подключается к конструкторам

Наконец, давайте используем @Autowired в конструкторе.

Мы увидим, что экземпляр FooFormatter вводится Spring в качестве аргумента конструктора Foodservice :

public class FooService {
    private FooFormatter fooFormatter;
    @Autowired
    public FooService(FooFormatter fooFormatter) {
        this.fooFormatter = fooFormatter;
    }
}

4. @Автоматические и необязательные зависимости

При создании компонента должны быть доступны зависимости @Autowired . В противном случае если Spring не сможет разрешить компонент для подключения, он выдаст исключение .

Следовательно, это предотвращает успешный запуск контейнера Spring, за исключением формы:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.FooDAO] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. 
Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

Чтобы исправить это, нам нужно объявить компонент требуемого типа:

public class FooService {
    @Autowired(required = false)
    private FooDAO dataAccessor; 
}

5. Автоматическое Устранение неоднозначности

По умолчанию Spring разрешает @Autowired записи по типу. Если в контейнере доступно более одного компонента одного и того же типа, фреймворк выдаст фатальное исключение .

Чтобы разрешить этот конфликт, нам нужно явно указать Spring, какой компонент мы хотим ввести.

5.1. Автоматическое подключение с помощью @квалификатора

Например, давайте посмотрим, как мы можем использовать аннотацию @Qualifier для указания требуемого компонента.

Сначала мы определим 2 компонента типа Форматер :

@Component("fooFormatter")
public class FooFormatter implements Formatter {
    public String format() {
        return "foo";
    }
}
@Component("barFormatter")
public class BarFormatter implements Formatter {
    public String format() {
        return "bar";
    }
}

Теперь давайте попробуем внедрить компонент Форматирования в класс FooService :

public class FooService {
    @Autowired
    private Formatter formatter;
}

В нашем примере для контейнера Spring доступны две конкретные реализации Форматирования . В результате Spring выдаст исключение NoUniqueBeanDefinitionException исключение при создании Foodservice :

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: 
No qualifying bean of type [com.autowire.sample.Formatter] is defined: 
expected single matching bean but found 2: barFormatter,fooFormatter

Мы можем избежать этого, сузив реализацию с помощью @Квалификатор аннотация:

public class FooService {
    @Autowired
    @Qualifier("fooFormatter")
    private Formatter formatter;
}

Когда существует несколько компонентов одного и того же типа, рекомендуется использовать @Квалификатор , чтобы избежать двусмысленности.

Пожалуйста, обратите внимание, что значение @Квалификатора аннотации совпадает с именем, объявленным в @Компоненте аннотации нашей FooFormatter реализации.

5.2. Автоматическое подключение с помощью Пользовательского классификатора

Spring также позволяет нам создавать свой собственный @классификатор аннотацию . Для этого мы должны предоставить @Квалификатор аннотацию с определением:

@Qualifier
@Target({
  ElementType.FIELD, ElementType.METHOD, ElementType.TYPE, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
public @interface FormatterType {  
    String value();
}

Затем мы можем использовать тип форматирования в различных реализациях для указания пользовательского значения:

@FormatterType("Foo")
@Component
public class FooFormatter implements Formatter {
    public String format() {
        return "foo";
    }
}
@FormatterType("Bar")
@Component
public class BarFormatter implements Formatter {
    public String format() {
        return "bar";
    }
}

Наконец, наша пользовательская аннотация квалификатора готова к использованию для автоматической проводки:

@Component
public class FooService {  
    @Autowired
    @FormatterType("Foo")
    private Formatter formatter;
}

Значение, указанное в @Target мета-аннотации, ограничивает применение квалификатора, которым в нашем примере являются поля, методы, типы и параметры.

5.3. Автоматическое подключение по имени

Spring использует имя компонента в качестве значения квалификатора по умолчанию. Он проверит контейнер и будет искать компонент с точным именем в качестве свойства для его автоматического подключения.

Следовательно, в нашем примере Spring сопоставляет имя свойства FooFormatter с реализацией FooFormatter . Поэтому он вводит эту конкретную реализацию при создании Foodservice :

public class FooService {
 @Autowired 
private Formatter fooFormatter; 
}

6. Заключение

В этой статье мы обсудили автопроводку и различные способы ее использования. Мы также рассмотрели способы решения двух распространенных исключений автоматической проводки, вызванных либо отсутствующим компонентом, либо неоднозначной инъекцией компонента.

Исходный код этой статьи доступен на проекте GitHub .