4 Stimmen

Abhängigkeitsinjektion mit autowire="constructor" bei mehreren Konstruktoren vorhanden?

Ich habe eine Texteditor-Klasse mit den folgenden Konstruktoren

 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 den Spring-Beanen habe ich

Was ich beobachte, ist, dass der Konstruktor mit zwei Argumenten konsistent aufgerufen wird. Ist das zufällig? Sollte Spring nicht eine Ausnahme werfen, weil es nicht weiß, welcher Konstruktor aufgerufen werden soll?

7voto

Sotirios Delimanolis Punkte 262318

Dies ist eine Folge davon, wie Spring Konstruktoren automatisch verdrahtet.

Zuerst werden alle Konstruktoren der bean Klasse abgerufen und sortiert. Öffentliche Konstruktoren mit abnehmender Argumentenzahl werden zuerst platziert, dann alle nicht-öffentlichen Konstruktoren wieder mit abnehmender Argumentenzahl. Das sind die Kandidatenkonstruktoren.

Dann durchläuft es diese Kandidaten und versucht, die Argumente aus der BeanFactory zu generieren. Wenn es nicht kann, weil eine Bean fehlt oder aus irgendeinem anderen Grund, überspringt es den Kandidaten. Wenn es Erfolg darin hat, die Argumente zu finden, gibt es dem aktuellen Kandidatenkonstruktor ein Gewicht basierend auf einer Reihe von Faktoren (Argumentenlistenlänge, wie nahe die Typen der Argumente den Parametern sind, usw.). Dann überprüft es das Gewicht des vorherigen Kandidaten und tauscht sie aus, wenn einer besser ist als der andere.

Wenn es am Ende dieses Prozesses einen Kandidatenkonstruktor gibt, verwendet Spring diesen.

Wenn du sagst, dass Spring deinen Konstruktor mit 2 Argumenten anstelle deines Konstruktors mit 3 Argumenten verwendet, bedeutet das, dass du keine Bean eines der Typen in deinem Konstruktor mit 3 Argumenten hast.

0voto

Vikash Mishra Punkte 615

Das folgende Beispiel kann Ihnen genaueres Verständnis vermitteln. Ich habe eine Klasse Employee, die eine Beziehung zur Qualifikation und Adresse hat. Die beans sind innerhalb der xml-Deklaration verfügbar.

Wir haben 4 Konstruktoren. Der 1. nimmt zwei Argumente, nämlich Adresse und Qualifikation, der 2. nur Qualifikation, der 3. die Adresse und der 4. alle Felder, beginnend mit id, name, dob, Adresse und Qualifikation.

//Konstruktor - 1

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

//Konstruktor - 2

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

//Konstruktor - 3

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

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

Fall 1: Angenommen, Konstruktor 1 und 4 sind nicht deklariert und wir haben keine constructor-arg in den Employee bean-Deklarationen.

Verhalten: Konstruktor 3 wird aufgerufen, da dies der letzte deklarierte Konstruktor ist. Wenn wir die Reihenfolge der Konstruktordefinitionen ändern, d.h. die Position von Konstruktor 2 mit 3 vertauschen.

Fall 2: Angenommen, Konstruktor 4 ist nicht deklariert und wir haben keine constructor-arg in den Employee bean-Deklarationen.

Verhalten: In diesem Fall wird Konstruktor 1 aufgerufen, da er den Typ Qualifikation und Adresse aus den bean-Deklarationen erhalten kann, was die Bedingung für die passenden Argumente für Konstruktor 1 erfüllt.

Fall 3: Angenommen, wir haben keine constructor-arg in den Employee bean-Deklarationen.

Verhalten: In diesem Fall wird ebenfalls Konstruktor 1 aufgerufen, da er den Typ Qualifikation und Adresse aus den bean-Deklarationen erhalten kann, was die Bedingung für die passenden Argumente für Konstruktor 1 erfüllt. Konstruktor 4 kann nicht aufgerufen werden, da id, name und dob nicht in der Bean-Deklarationsdatei verfügbar sind. Daher ist der 1. Konstruktor der am besten passende Konstruktor, da Qualifikation und Adresse in der Bean-Deklaration verfügbar sind.

Fall 4: Angenommen, wir haben constructor-arg in den Employee bean-Deklarationen und alle Konstruktoren sind verfügbar.

Verhalten: Der 4. Konstruktor wird aufgerufen, da id, name, dob, Qualifikation und Adresse in der Bean-Deklarationsdatei verfügbar sind. Daher werden die ersten 3 Argumente aus constructor-arg und die letzten beiden aus der Bean-Deklaration selbst übernommen, sodass alle Argumente aus dem 4. Konstruktor übereinstimmend sind und daher der 4. Konstruktor aufgerufen wird. Fazit: Die Fälle und Verhaltensweisen legen nahe, dass der Spring Container bei mehreren Konstruktoren alle abhängigen Eigenschaften überprüft und basierend auf allen verfügbaren Eigenschaften überprüft, welcher Konstruktor verwendet werden kann, um das Objekt zu erstellen, wobei möglichst viele Eigenschaften initialisiert werden können.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X