Использование аннотации @Autowired в 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()";
}
}
Вы должны войти под своим аккаунтом чтобы оставлять комментарии