Аннотация @Autowired: что к чему?
Решил рассказать немного про аннотацию @Autowired. Принцип её работы очень прост.
Допустим у нас есть bean-зависимости:
@Configuration public class Config { // тип бина - ServiceDependency, имя - dependency public ServiceDependency dependency() { return new ServiceDependencyImpl() } }
@Service public class MyService { private ServiceDependency dependency; @Autowired public MyService(ServiceDependency dependency) { this.dependency = dependency; } }
И при создании контекста Spring автоматически определит, что для создания MyService требуется bean типа ServiceDependency (или наследник), найдёт его у себя, в рамках подставит зависимость ServiceDependencyImpl в bean MyService.
На самом деле, начиная со Spring 4.0 аннотацию @Autowired можно не ставить на конструктор, если он единственный в классе.
Другие варианты использования аннотации
@Autowired можно ставить непосредственно на поле. Да-да, это будет работать и с private-полями:
@Service public class MyService { @Autowired private ServiceDependency dependency; // бизнес-методы }
Также аннотацию можно ставить на сеттеры:
@Service public class MyService { private ServiceDependency dependency; @Autowired public void setDependency(ServiceDependency dependency) { this.dependency = dependency; } }
Но можно так же ставить и на отдельные методы, например:
@Service public class MyService { private ServiceDependency dependency; @Autowired public void init(ServiceDependency dependency) { this.dependency = dependency; } }
Что ещё?
Предположим, что бинов типа ServiceDependency несколько (допустим dependency1 и dependency2). Тогда, чтобы задать конкретный bean, необходимо использовать аннотацию @Qualifier:
@Service public class MyService { private ServiceDependency dependency; @Autowired public void setDependency( @Qualifier("dependency1") ServiceDependency dependency ) { this.dependency = dependency; } }
А если мы захотим использовать все бины?
Сделать это можно простым способом:
@Service public class MyService { private ServiceDependency[] dependencies; @Autowired public void setDependency(ServiceDependency[] dependencies) { this.dependency = dependency; } }
И Spring вставит (удивительно) все бины, реализующие интерфейс ServiceDependency. То же самое верно и для типизированных коллекций. Как ни странно, но порядком следования в этой коллекции можно управлять с помощью аннотации @Order.
Но самое замечательное, вот это:
@Autowired private Map<String, StringCallable> map;
Spring автоматически подставит не только сами бины, но и имена бинов в качестве ключей. Это может быть эффективно использовано, например, в паттерне «стратегия».
Есть вопрос? Напишите в комментариях!