Використання анотації @Autowire в Spring 3

лютого
12
2012
Мітки: autowired java spring

Анотація @Autowired відзначає конструктор, поле або метод як такий, що вимагає автозаповнення ін'єкцією залежності Spring. Дана анотація вперше з'явилася в Spring 2.5.

Щоб анотація @Autowire присвоїла змінній значення відповідного bean'а, необхідно щоб цей bean або був оголошений в xml конфігурації програми, або існував клас з відповідною ін'єкцією керування.

Що таке @Autowired?

Якщо ж опустити всі розумні слова, то корисну функціональність анотації @Autowired можна описати наступним чином ... Використовуючи цю анотацію, не потрібно піклуватися про те, як найкраще передати класу або bean'у екземпляр іншого bean'a. Фреймворк Spring сам знайде потрібний bean і підставить його значення у властивість, яка зазначена анотацією @Autowired.

@Autowired і властивість класу

Властивості класу з анотацією @Autowired заповнюються відповідними значеннями відразу після створення bean'а і перед тим, як будь-який з методів класу буде викликано. Приклад:


    @Autowired
    private FieldService propertyService;

@Autowired і сеттер

Традиційне використання анотації. Приклад:


    @Autowired
    public void setSetterService(SetterService setterService) {
        this.setterService = setterService;
    }

@Autowired і конструктор класу

Тільки один конструктор може виконувати цю анотацію. Цей конструктор може бути будь-якого типу (private, protected), а не тільки pubic.


    @Autowired
    public BeanContainer(ConstructorService constructorService) {
        this.constructorService = constructorService;
    }

@Autowired і метод

Анотація @Autowire може бути використана в методі з будь-яким ім'ям і з будь-якою кількістю аргументів. В цьому випадку Spring спробує привласнити кожному(!) аргументу значення відповідних bean'ів. Метод не зобов'язаний бути public. Приклад:


    @Autowired
    public void multipleArguments(SetterAService setterAService,
            SetterBService setterBService) {
        this.setterAService = setterAService;
        this.setterBService = setterBService;
    }

Використання (require=false)

Конструкція 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)}

@Autowired і @Qualifier

За допомогою анотації @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: Завантажити

Коментарі (1)

bumer7721
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()";
}
}
Ви повинні увійти під своїм аккаунтом щоб залишати коментарі