Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection with autowire="constructor" when multiple constructors are present?

Tags:

java

spring

I have text editor class with below constructors

 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;
           }
        }

In spring-beans i have

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

what i observe is constructor with two arguments is called consistently. Is it random? Should not spring throw exception becoz it does not know which constructor needs to be called?

like image 588
M Sach Avatar asked Mar 20 '23 12:03

M Sach


1 Answers

This is a consequence of how Spring autowires constructors.

The first thing it does is gets all the bean class' constructors and sorts them, putting public constructors first with decreasing amount of arguments, then all non-public constructors again with decreasing amount of arguments. These are the candidate constructors.

It then iterates through these candidates, trying to generate the arguments from the BeanFactory. If it can't because a bean is missing or for whatever other reason, it skips the candidate. If it succeeds in finding the arguments, it gives the current candidate constructor a weight based on a number of factors (argument list length, how close the types of the arguments vs the parameters are, etc.). It then checks the previous candidate's weight and swaps them if one is better than the other.

If there is a candidate constructor at the end of this process, Spring uses it.

If you're saying that Spring is using your 2 arg constructor over your 3 arg constructor, then that means you don't have a bean of one of the types in your 3 arg constructor.

like image 141
Sotirios Delimanolis Avatar answered Apr 06 '23 03:04

Sotirios Delimanolis