Анотація @Autowired відзначає конструктор, поле або метод як такий, що вимагає автозаповнення ін'єкцією залежності Spring. Дана анотація вперше з'явилася в Spring 2.5.
Щоб анотація @Autowire присвоїла змінній значення відповідного bean'а, необхідно щоб цей bean або був оголошений в xml конфігурації програми, або існував клас з відповідною ін'єкцією керування.
Якщо ж опустити всі розумні слова, то корисну функціональність анотації @Autowired можна описати наступним чином ... Використовуючи цю анотацію, не потрібно піклуватися про те, як найкраще передати класу або bean'у екземпляр іншого bean'a. Фреймворк Spring сам знайде потрібний bean і підставить його значення у властивість, яка зазначена анотацією @Autowired.
Властивості класу з анотацією @Autowired заповнюються відповідними значеннями відразу після створення bean'а і перед тим, як будь-який з методів класу буде викликано. Приклад:
@Autowired
private FieldService propertyService;
Традиційне використання анотації. Приклад:
@Autowired
public void setSetterService(SetterService setterService) {
this.setterService = setterService;
}
Тільки один конструктор може виконувати цю анотацію. Цей конструктор може бути будь-якого типу (private, protected), а не тільки pubic.
@Autowired
public BeanContainer(ConstructorService constructorService) {
this.constructorService = constructorService;
}
Анотація @Autowire може бути використана в методі з будь-яким ім'ям і з будь-якою кількістю аргументів. В цьому випадку Spring спробує привласнити кожному(!) аргументу значення відповідних bean'ів. Метод не зобов'язаний бути public. Приклад:
@Autowired
public void multipleArguments(SetterAService setterAService,
SetterBService setterBService) {
this.setterAService = setterAService;
this.setterBService = setterBService;
}
Конструкція require=false повідомляє фреймворк про те, що наявність відповідного bean'у не є обов'язковим при компіляції програми. Приклад:
@Autowired(required=false)
private NotBeanService notBeanService;
У випадку, якщо анотація не була оголошена з required=false і bean відсутній у програмі, користувач отримає виняток:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'beanContainer': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.seostella.springautowire.domain.NotBeanService com.seostella.springautowire.BeanContainer.notBeanService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [com.seostella.springautowire.domain.NotBeanService] 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)}
За допомогою анотації @Qualifier можна помітити конкретного кандидата для автозаповнення якщо кандидатів декілька. Наприклад, є два bean'а:
<bean id="fooService1" class="com.seostella.springautowire.domain.FooService">
<property name="name" value="fooService1" />
</bean>
<bean id="fooService2" class="com.seostella.springautowire.domain.FooService"
p:name="fooService2" />
Ці два bean'а описують один і той же клас FooService:
package com.seostella.springautowire.domain;
/**
*
* @author seostella.com
*/
public class FooService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String doStuff(){
return name + ".doStuff()";
}
}
Щоб при автозаповненні отримати другий bean з ідентифікатором fooService2, необхідно скористатися анотацією @Qualifier. Приклад:
@Autowired
@Qualifier("fooService2")
private FooService fooService;
Перевірити, що це саме другий bean дуже легко: метод doStuff перший bean'а поверне рядок fooService1.doStuff(), а метод doStuff другого bean'а - fooService2.doStuff().
Також @Qualifier можна використовувати для конкретного аргументу в методі з декількома аргументами. Наприклад:
@Autowired
public void multipleArguments(@Qualifier("main") SetterAService setterAService,
SetterBService setterBService) {
this.setterAService = setterAService;
this.setterBService = setterBService;
}
В якості бонуса - код веб-програми, що демонструє всі перераховані вище прийоми з анотацією @Autowired: Завантажити
25 січня 2013 р. 18:40
|
чи обов'язково повинні бути
public String getName() { return name; } public void setName(String name) { this.name = name; } в класі якщо писати так public class FooService { @Autowired private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public String doStuff(){ return name + ".doStuff()"; } } |