Iniezione delle dipendenze basata sul costruttore

La DI basata sul costruttore viene eseguita quando il contenitore richiama un costruttore di classi con un numero di argomenti, ognuno dei quali rappresenta una dipendenza dall'altra classe.

Esempio

L'esempio seguente mostra una classe TextEditor che può essere inserita solo in dipendenza con l'inserimento del costruttore.

Cerchiamo di avere un IDE Eclipse funzionante e di eseguire i seguenti passaggi per creare un'applicazione Spring:

Passi Descrizione
1 Crea un progetto con un nome SpringExample e crea un pacchetto com.tutorialspoint sottosrc cartella nel progetto creato.
2 Aggiungere le librerie Spring richieste utilizzando l' opzione Aggiungi JAR esterni come spiegato nel capitolo Esempio Spring Hello World .
3 Crea classi Java TextEditor , SpellChecker e MainApp nel pacchetto com.tutorialspoint .
4 Crea il file di configurazione Beans Beans.xml sottosrc cartella.
5 Il passaggio finale consiste nel creare il contenuto di tutti i file Java e nel file di configurazione Bean ed eseguire l'applicazione come spiegato di seguito.

Ecco il contenuto di TextEditor.java file -

package com.tutorialspoint;

public class TextEditor {
   private SpellChecker spellChecker;

   public TextEditor(SpellChecker spellChecker) {
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

Di seguito è riportato il contenuto di un altro file di classe dipendente SpellChecker.java

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }
   public void checkSpelling() {
      System.out.println("Inside checkSpelling." );
   }
}

Di seguito è riportato il contenuto del file MainApp.java file

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      TextEditor te = (TextEditor) context.getBean("textEditor");
      te.spellCheck();
   }
}

Di seguito è riportato il file di configurazione Beans.xml che ha la configurazione per l'iniezione basata sul costruttore -

<?xml version = "1.0" encoding = "UTF-8"?>

<beans xmlns = "http://www.springframework.org/schema/beans"
   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation = "http://www.springframework.org/schema/beans
   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <!-- Definition for textEditor bean -->
   <bean id = "textEditor" class = "com.tutorialspoint.TextEditor">
      <constructor-arg ref = "spellChecker"/>
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id = "spellChecker" class = "com.tutorialspoint.SpellChecker"></bean>

</beans>

Una volta terminata la creazione dei file di configurazione dei bean e dei sorgenti, eseguiamo l'applicazione. Se tutto va bene con la tua applicazione, stamperà il seguente messaggio:

Inside SpellChecker constructor.
Inside TextEditor constructor.
Inside checkSpelling.

Risoluzione degli argomenti del costruttore

Potrebbe esserci un'ambiguità durante il passaggio degli argomenti al costruttore, nel caso in cui ci siano più parametri. Per risolvere questa ambiguità, l'ordine in cui gli argomenti del costruttore sono definiti in una definizione di bean è l'ordine in cui quegli argomenti vengono forniti al costruttore appropriato. Considera la seguente classe:

package x.y;

public class Foo {
   public Foo(Bar bar, Baz baz) {
      // ...
   }
}

La seguente configurazione funziona bene:

<beans>
   <bean id = "foo" class = "x.y.Foo">
      <constructor-arg ref = "bar"/>
      <constructor-arg ref = "baz"/>
   </bean>

   <bean id = "bar" class = "x.y.Bar"/>
   <bean id = "baz" class = "x.y.Baz"/>
</beans>

Controlliamo un altro caso in cui passiamo diversi tipi al costruttore. Considera la seguente classe:

package x.y;

public class Foo {
   public Foo(int year, String name) {
      // ...
   }
}

Il contenitore può anche utilizzare la corrispondenza del tipo con i tipi semplici, se si specifica esplicitamente il tipo dell'argomento del costruttore utilizzando l'attributo type. Ad esempio:

<beans>

   <bean id = "exampleBean" class = "examples.ExampleBean">
      <constructor-arg type = "int" value = "2001"/>
      <constructor-arg type = "java.lang.String" value = "Zara"/>
   </bean>

</beans>

Infine, il modo migliore per passare gli argomenti del costruttore, utilizzare l'attributo index per specificare esplicitamente l'indice degli argomenti del costruttore. Qui, l'indice è basato su 0. Ad esempio:

<beans>

   <bean id = "exampleBean" class = "examples.ExampleBean">
      <constructor-arg index = "0" value = "2001"/>
      <constructor-arg index = "1" value = "Zara"/>
   </bean>

</beans>

Una nota finale, nel caso in cui stai passando un riferimento a un oggetto, devi usare ref attributo del tag <constructor-arg> e se stai passando un valore direttamente, dovresti usare value attributo come mostrato sopra.