back to top

Core container – Setter Dependency Injection – Guida Java Spring

L'uso della Constructor Dependency Injection può portare alla creazione di dipendenze cicliche tra i beans. Ad esempio se un oggeto A ha bisogno per essere instanziato di un oggetto B, ma allo stesso tempo l'oggetto B ha bisogno dell'oggetto A, si crea un dipendenza che non può essere risolta usando la Constructor Dependency Injection.

In casi come questi si deve usare la Setter Dependency Injection che è molto simile alla Constructor ma la differenza sta nel fatto che le dipendenze vengono iniettate dopo che l'oggetto è stato instanziato. Vediamo un esempio:

public class Bean2 {

  private GenericService genericService;

  public void setGenericService(GenericService genericService) {
    this.genericService = genericService;
  }

  public GenericService getGenericService() {
    return genericService;
  }

  /**
   * Business logic.............
   */

}

nell'applicationContext.xml

<bean id="setterBean" class="it.mrwebmaster.di.setter.Bean2">
  <property name="genericService" ref="genericService" />
</bean>

Oltre a risolvere il problema delle dipenze circolari la Setter Dependency Injection consente anche di riconfigurare a runtime i beans, per questi motivi viene preferita alla Constructor. Alcune scuole di pensiero però dicono che l'ottimo sarebbe quello di usare entrabe: la Constructor per le dipendenze necessarie e la Setter per quelle opzionali. Si consiglia comunque di usare la Setter poichè è molto raro che ci siano delle dipendenze opzionali.

Oltre all'uso di base della DI ci sono altre funzionalità che Spring offre, ad esempio si possono iniettare stringhe vuote o campi null:

<!-- NULL VALUE 1 -->
<bean id="nullBean1" class="it.mrwebmaster.di.constructor.bean" factory-method="createBean">
  <constructor-arg value="0" type="java.lang.Integer" />
  <constructor-arg value="" type="java.lang.String" />
  <constructor-arg type="it.mrwebmaster.di.constructor.GenericService"><null/></constructor-arg>
</bean>

<!-- NULL VALUE 2 -->
<bean id="nullBean2" class="it.mrwebmaster.di.setter.Bean2">
  <property name="genericService"><null/></property>
</bean>

Spring offre anche una gestione delle Collection del tipo List, Set, Map, e Properties attraverso i tag list, set, map, e props:

public class CollectionBean {

  private List<GenericService> beanList;

  private Properties beanProps;

  private Set<String> beanSet;

  private Map<Integer, String> beanMap;

  /**
   * business logic......................
   */

  public List<GenericService> getBeanList() {
    return beanList;
  }

  public Map<Integer, String> getBeanMap() {
    return beanMap;
  }

  public Properties getBeanProps() {
    return beanProps;
  }

  public Set<String> getBeanSet() {
    return beanSet;
  }

  public void setBeanList(List<GenericService> beanList) {
    this.beanList = beanList;
  }

  public void setBeanMap(Map<Integer, String> beanMap) {
    this.beanMap = beanMap;
  }

  public void setBeanProps(Properties beanProps) {
    this.beanProps = beanProps;
  }

  public void setBeanSet(Set<String> beanSet) {
    this.beanSet = beanSet;
  }
}

nell'applicationContext.xml

<!-- COLLECTION BEAN -->
<bean id="collectionBean" class="it.mrwebmaster.di.collection.CollectionBean">

  <!-- LIST -->
  <property name="beanList">
    <list>
      <ref bean="genericService"/>
    </list>
  </property>

  <!-- PROPERTIES -->
  <property name="beanProps">
    <props>
      <prop key="prop1">value1</prop>
      <prop key="prop2">value2</prop>
      <prop key="prop3">value3</prop>
    </props>
  </property>

  <!-- SET -->
  <property name="beanSet">
    <set>
      <value>a</value>
      <value>b</value>
    </set>
  </property>

  <!-- MAP -->
  <property name="beanMap">
    <map>
      <entry key="1" value="value1" />
    </map>
  </property>
</bean>

Si lascia al lettore l'approfondimento su altre questioni come il merge delle collection, gli inner beans e i collaborators.

Pubblicitร