2014-02-20 3 views
4

У меня есть текстовый редактор класс с ниже конструкторамиВключение зависимостей с autwire = "конструктор" при наличии нескольких конструкторов?

public class TextEditor { 
     private SpellChecker spellChecker; 

     private SpellChecker1 spellChecker1; 

     private SpellChecker2 spellChecker2; 

    public TextEditor(SpellChecker spellChecker) { 
      this.spellChecker = spellChecker; 
     } 

     public TextEditor(SpellChecker2 spellChecker2) { 
       this.spellChecker2 = spellChecker2; 
      } 

     public TextEditor(SpellChecker spellChecker, SpellChecker1 spellChecker1,SpellChecker2 spellChecker2) { 
       this.spellChecker = spellChecker; 
       this.spellChecker1 = spellChecker1; 
       this.spellChecker2 = spellChecker2; 
      } 

     public TextEditor(SpellChecker spellChecker, SpellChecker1 spellChecker1) { 
       this.spellChecker = spellChecker; 
       this.spellChecker1 = spellChecker1; 
      } 
     } 

В пружинной фасоли я быть_наст

<bean id="textEditor" class="com.TextEditor" autowire="constructor"> 
</bean> 

Я наблюдаю конструктор с двумя аргументами называются последовательно. Это случайно? Не должно быть исключение весны, потому что он не знает, какой конструктор нужно назвать?

+2

Почему он не должен знать, какой конструктор нужно назвать. Он определяет типы ввода, основанные на доступных конструкторах, выполняет проверку в контексте, какой конструктор может быть удовлетворен в лучшем случае и выполняет его. –

+0

Тогда почему не был создан конструктор с 3 аргументами? –

+0

Есть ли в наличии bean-тип 'SpellChecker2'? Без полной картины трудно сказать. –

ответ

5

Это следствие того, как конструкторы Spring autowires.

Первое, что он делает, это создавать все конструкторы класса bean и сортировать их, ставя публичные конструкторы сначала с уменьшением количества аргументов, а затем все непубличные конструкторы снова с уменьшением количества аргументов. Это конструкторы-кандидаты.

Затем он повторяет эти кандидаты, пытаясь сгенерировать аргументы из BeanFactory. Если это невозможно, поскольку отсутствует компонент или по какой-либо другой причине, он пропускает кандидата. Если ему удастся найти аргументы, он дает текущему конструктору-кандидату вес, основанный на ряде факторов (длина списка аргументов, насколько близки типы аргументов и параметры и т. Д.). Затем он проверяет вес предыдущего кандидата и меняет его, если он лучше другого.

Если в конце этого процесса есть конструктор-кандидат, Spring использует его.

Если вы говорите, что Spring использует ваш конструктор 2 arg над вашим конструктором arg 3, то это означает, что у вас нет компонента одного из типов в вашем конструкторе arg 3.

+0

Это говорит мне, что «никогда не использовать' autowire = constructor' », если существует более одного конструктора :) И поскольку в будущем можно добавить больше конструкторов и забыть xml, просто« никогда не используйте 'autowire = constructor'" – Andrejs

0

Более точно ниже пример может помочь вам понять, поэтому у меня есть один сотрудник Employee, и у него есть отношения с квалификацией и адресом, а bean доступны внутри объявления xml.

<bean id="qualification" class="com.Autowiring.constructor.Qualification"> 
    <property name="highestQualification" value="BTech"/> 
    <property name="certifcations" value="SCJP"/> 
</bean> 

<bean name="address" class="com.Autowiring.constructor.Address"> 
    <property name="city" value="Bangalore" /> 
    <property name="zip" value="560054" /> 
    <property name="building" value="Building One" /> 
</bean> 

У нас есть 4 Конструкторы 1-й взять два аргумента, т.е. адреса и квалификации и второй принимает квалификации и третий конструктор принимает адрес, а затем четвёртую один берет на себя все поля, начиная от ид, имя, DOB, адрес и квалификацию.

// Конструктор - 1

public Employee(Address address, Qualification qualification) { 
    super(); 
    System.out.println(1); 
    this.address = address; 
    this.qualification = qualification; 
} 

// Конструктор - 2

public Employee(Qualification qualification) { 
    super(); 
    System.out.println(2); 
    this.qualification = qualification; 
} 

// Конструктор - 3

public Employee(Address address) { 
    super(); 
    System.out.println(3); 
    this.address = address; 
} 

// Конструктор - 4

public Employee(int id, String name, Date dob, Address address, 
     Qualification qualification) { 

    super(); 
    System.out.println(4); 
    this.id = id; 
    this.name = name; 
    this.dob = dob; 
    this.address = address; 
    this.qualification = qualification; 
} 

Case-1: Предположим, что конструктор 1 и 4 не объявлен, и у нас нет конструктора-arg в объявлениях компонента-компонента.

Поведение: конструктор 3 будет называться как это последний конструктор заявил, если мы изменим порядок определения Конструкторы т.е. поменять положение конструктора 2 с 3.

Case-2: Давайте предположим, что конструктор 4 не объявлен, и у нас нет конструктора-arg в объявлениях компонента-компонента.

Поведение: В этом случае конструктор 1 будет называться, как он может получить тип квалификацию и адрес, доступный в декларациях боба, так что это удовлетворяет условие для аргументов соответствия для конструктора 1.

Случай-3: Предположим, у нас нет конструктора-arg в объявлениях компонента-сотрудника.

Поведение: В этом случае также конструктор 1 будет называться, как он может получить тип квалификацию и адрес, доступный в декларациях боба, так что это удовлетворяет условие для аргументов соответствия для конструкторы 1, но это не будет способный вызвать 4-й конструктор, поскольку id, name и dob недоступны в файле объявления bean, поэтому первый конструктор является лучшим конструктором соответствия, так как мы имеем квалификацию и адрес, доступные в объявлении bean.

Case-4: Предположим, что у нас есть конструктор-arg в объявлениях bean-компонентов, и все конструкторы доступны.

Поведение: Он будет в состоянии назвать 4-й конструктора как идентификатор, имя, DOB, квалификация и адрес доступен в файле декларация боба, поэтому первый 3 аргумента будет поступать из конструктора арг и последние двух будет исходить от объявление самого компонента, поэтому будет вызываться все аргументы из 4-го конструктора, соответствующего, следовательно, 4-го конструктора. Заключение. Таким образом, случаи и поведение показывают, что в случае нескольких конструкторов весенний контейнер пытается проверить все зависимые свойства и проверять на основе всего доступного свойства, которое среди конструкторов можно использовать для создания объекта, где максимально возможные свойства могут быть инициализированы.

Смежные вопросы