back to top

Core container – Constructor Dependency Injection – Guida Java Spring

Vediamo ora, attraverso un esempio, come usare la Constructor Dependency Injection. Creiamo il nostro bean che dipende da un servizio generico:

package it.mrwebmaster.di.constructor;

public class Bean {

  private GenericService genericService;

  private String beanName;

  /**
   * Costruttore
   * @param genericService
   * @param beanName
   */
  public Bean(GenericService genericService, String beanName) {
    super();
    this.genericService = genericService;
    this.beanName = beanName;
  }

  /**
   * Metodo pubblico
   */
  public void doIt(){
    System.out.println(beanName + " doing something");
    genericService.dosomething();
  }

}

configuriamo la dependency nell'applicationContext.xml

<bean id="genericService" class="it.mrwebmaster.di.constructor.GenericServiceImpl" scope="singleton" />

<bean id="constructorBean" class="it.mrwebmaster.di.constructor.bean">
  <constructor-arg value="beanName"/>
  <constructor-arg ref="genericService"/>
</bean>

Come si evince dall'esempio per usare la Constructor Dependency Injection dobbiamo usare il tag constructor-arg usando gli attributi ref o value. L'attibuto ref serve per passare come arogmento un altro bean già instanziato nell'IoC container, mentre l'attributo value serve per passare valori predefiniti come stringhe o numeri.

Nell'esempio il costruttore della classe bean accetta in input un GenericService e una String, ma nell'esempio si è voluto invertire l'ordine degli argomenti per mostrare come Spring associ gli argomenti attraverso il loro tipo. Questo tipo di comportamento va bene quando tutti gli argomenti sono di tipo diverso, ma come facciamo a specificare l'ordine se gli argomenti sono dello stesso tipo? Il tag constructor-arg mette a disposizione l'attributo index che indica a Spring l'ordine con il quale passare i parametri.

<bean id="constructorBean" class="it.mrwebmaster.di.constructor.bean">
  <constructor-arg value="beanName" index="1" />
  <constructor-arg ref="genericService" index="0" />
</bean>

Altro caso ambiguo potrebbe essere quello in cui il construttore accetti in input due parametri che posso essere entrambi rappresentati da una stringa, ad esempio:

public bean(GenericService genericService, String beanName, Integer invocationTimes) {
  super();
  this.genericService = genericService;
  this.beanName = beanName;
  this.invocationTimes = invocationTimes;
}

e nell'applicationContext.xml

<bean id="constructorBean2" class="it.mrwebmaster.di.constructor.bean">
  <constructor-arg value="0" />
  <constructor-arg value="beanName" />
  <constructor-arg ref="genericService" />
</bean>

In questo caso Spring da errore poichè "0" può essere sia una stringa che un numero. Per risolvere questo problema si può usare l'attriburo index o l'attributo type in questo modo:

<bean id="constructorBean2" class="it.mrwebmaster.di.constructor.bean">
  <constructor-arg value="0" type="java.lang.Integer" />
  <constructor-arg value="beanName" type="java.lang.String" />
  <constructor-arg ref="genericService" />
</bean>

L'attributo constructor-arg può essere usato anche per passare parametri al factory method:

public static bean createBean(GenericService genericService, String beanName, Integer invocationTimes) {
  bean b = new bean(genericService, beanName, invocationTimes);
  // do somethig.......
  return b;
}

nell'applicationContext.xml

<bean id="constructorBean3" class="it.mrwebmaster.di.constructor.bean" factory-method="createBean">
  <constructor-arg value="0" type="java.lang.Integer" />
  <constructor-arg value="beanName" type="java.lang.String" />
  <constructor-arg ref="genericService" />
</bean>
PubblicitÃ