autowire byType согласно Spring 4.1.6 to Documentation

Разрешает автоматическое связывание свойства, если в контейнере существует только один компонент типа свойства. Если существует более одного, выдается фатальное исключение, указывающее на то, что вы не можете использовать автосвязывание byType для этого bean-компонента. Если подходящих бобов нет, ничего не происходит; свойство не установлено. - ИЗ SPRING REFERENCE GUID 4.1.6

<bean id="person" class="autowire.Person" autowire="byType" />

<bean id="invisible" class="autowire.Ability" >
    <property name="skill" value="Invisible" />
</bean>

<bean id="invisible2" class="autowire.Ability" >
    <property name="skill" value="Invisible" />
</bean>

Определения классов:

package autowire;

public class Person 
{
private Ability ability;
//...
}

package autowire;

public class Ability {

    private String skill;

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }

}

Мне удалось определить 2 bean-компонента одного типа класса "autowire.Ability". Я не получил фатальное исключение. Правильно ли я понимаю?


person Vinodh Thiagarajan    schedule 24.04.2015    source источник
comment
Есть ли у вашего человека метод setAbility? Поскольку у вас теперь есть только поле, а не свойство.   -  person M. Deinum    schedule 25.04.2015
comment
Значит, поле и свойство — это разные вещи? я думал, что переменная-член POJO является свойством.   -  person Vinodh Thiagarajan    schedule 25.04.2015
comment
Нет, я предлагаю прочитать спецификацию Java Bean.   -  person M. Deinum    schedule 27.04.2015


Ответы (2)


Вы почти у цели (чтобы получить ошибку). Вам нужно сообщить Spring, какие атрибуты класса должны быть автоматически подключены. Аннотируйте Person.ability с помощью @Autowired, и вы должны получить сообщение об ошибке.

import org.springframework.beans.factory.annotation.Autowired;

public class Person 
{
  @Autowired
  private Ability ability;
  //...
}

Или, что еще лучше, создайте конструктор и подключите его автоматически, так как внедрение атрибутов считается плохой практикой.

public class Person 
{
  private Ability ability;

  @Autowired
  public Person(Ability ability) {
    this.ability = ability;
  }
  //...
}

Spring не предполагает, какие атрибуты должны быть введены (автоматически подключены), поэтому вам нужно указать, какие из них вы хотите внедрить.

person Augusto    schedule 24.04.2015

Поведение, которое вы видите, правильное, вы можете определить столько bean-компонентов одного типа, сколько хотите, проблема возникает, когда Autowired bean (компонент, служба и т. д.) ожидает зависимость определенного типа и не может быть разрешена, потому что есть много которое соответствует определению поля, например:

Если Person объявлено как @Component и объявлено поле @Autowired типа Ability, например:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class Person {
    @Autowired
    private Ability ability;
}

Наличие двух bean-компонентов invisible и invisible2 вызовет ожидаемое исключение, потому что Spring не сможет узнать, какой из двух bean-компонентов нужно внедрить в Person.

Чтобы запустить этот пример, вам нужно включить контекст приложения сканирования.

Надеюсь это поможет,

Хосе Луис

person jbarrueta    schedule 24.04.2015