Buenas Practicas De Configuracion De Spring

De Dos Ideas.
Revisión del 12:23 25 feb 2009 de Gianu (discusión | contribuciones) (Integrar archivos de configuración mediante ApplicationContext y no utilizando import)
Saltar a: navegación, buscar

Aqui hay una recopilacion de buenas practicas a la hora de configurar Spring, las mismas son traducciones de: Twelve Best Practices for Spring XML

Evitar el uso de autowiring

Spring puede hacer autowiring de dependencias haciendo instropeccion de las clases, logrando de esta manera evitar que uno tenga que especificar las propiedades del bean o los argumentos de los constructores. Se puede hacer autowiring de las propiedades de los beans ya sea por nombre de propiedad o por tipo. En el caso de los constructores, solo se permite por tipo. Tambien se puede especificar el modo "autodetect autoriwiring", que deja que Spring elija el mecanismo mas apropiado. Miremos el siguiente código:

<bean id="invasorService"

       class="com.dosideas.spring.InvasorService"
       autowire="byName"/>

Los nombres de las propiedades de la clase InvasorService son usadas para buscar instancias de beans en el contenedor. El uso de Autowiring nos salva de tipear mucho código. De todas formas, nunca deberiamos utilizar Autowiring en una aplicación real porque perjudicamos la legibilidad de nuestro archivo de configuración y la mantenibilidad del mismo. Parece una buena idea hacer que nuestros archivos XML de configuración sean pequeños, pero esto aumenta en gran medida la complejidad de comprensión de la solución.

Spring tambien nos permite mezclar las dos técnicas (Autowiring y no-autowiring), pero con esto solamente lograriamos hacer mucho mas confusa la configuración.

Usar convenciones de nomenclatura

Esta es la misma filosofia que utilizamo con el código Java. Usar una nomenclatura clara, descriptiva y consistente en todo el proyecto es de gran ayuda para que los desarrolladores entiendan la configuración XML. Para el id de los Beans, por ejemplo, se puede seguir la convención de atributos de una clase Java. El Bean ID de una instancia de InvasorDAO podria ser InvasorDAO. En proyectos grandes, se puede agregar el nombre del paquete como prefijo del Bean ID.

Usar formas abreviadas de configuración

Las formas abreviadas son mas faciles de leer, dado que transforma el valor de los elementos hijos en atributos del elemento padre. Por ejemplo:

<bean id="invasorService"

     class="com.dosideas.spring.InvasorService">
      <property name="nombreInvasor">
         <value>Zim</value>
      </property>
      <constructor-arg>
         <ref bean="invasorDAO">
      </constructor-arg>

</bean>

puede ser reescrito de forma abreviada:

<bean id="InvasorService"

     class="com.dosideas.spring.InvasorService">
       <property name="nombreInvasor" value="Zim"/>
       <constructor-arg ref="invasorDAO"/>

</bean>

Este feature esta disponible desde la versión 1.2 de Spring. Vale aclarar que no existe abreviacion para el elemento <ref local="...">.

Esta forma de abreviar nuestra configuración no solo nos evita tipear, tambien deja al archivo XML mucho mas claro.

Utilizar type en vez de index para los argumentos del constructor

Spring permite utilizar indices (que comienzan en cero) para resolver el problema de ambigüedad cuando un constructor tiene mas de un argumento del mismo tipo, o cuando se utiliza el atributo value para asignar el valor. Por ejemplo, en vez de:

<bean id="InvasorService"

       class="com.dosideas.spring.InvazorService">
       <constructor-arg index="0" value="Zim"/>
       <constructor-arg index="1" value="100"/>

</bean>

es mejor utilizar el atributo type de la siguiente manera:

<bean id="invasorService"

       class="com.dosideas.spring.InvasorService">
       <constructor-arg type="java.lang.String" value="Zim"/>
       <constructor-arg type="int" value="100"/>

</bean>

Utilizar index es mas sencillo, ya que tipeamos menos, pero es mas propenso a errores y mucho mas dificil de leer que si utilizamos type. Se deberia utilizar index solamente cuando se presenta una ambigüedad en los argumentos del constructor.

En lo posible, reutilizar definiciones de Beans

Spring ofrece un mecanismo de pseudo-herencia que reduce la duplicacion de informacion en los archivos de configuracion. Una definición de un Bean hijo puede heredar la información de configuracion de sus padres, los cuales sirven como un "template" para los beans hijos. En grandes proyectos el uso de este feature deberia ser obligatorio. Todo lo que se necesita hacer es especificar abstract=true en el Bean padre y referenciar a dicho Bean desde los Beans hijos. Por ejemplo:

<bean id="abstractInvasorService" abstract="true"

       class="com.dosideas.spring.AbstractInvasorService">
       <property name="nombreInvasor" value="Zim"/>

</bean>

<bean id="InvasorService"

       parent="abstractInvasorService"
       class="com.dosideas.spring.InvasorService">
       <property name="robotAsignado" value="Gir"/>

</bean>

El bean InvasorService hereda el valor Zim para la propiedad nombreInvasor del bean abstractInvasorService. Una aclaración: Si no se especifica el nombre de una clase un un factory method en la definición de un bean, este bean es implicitamente abstracto.

Integrar archivos de configuración mediante ApplicationContext y no utilizando import

Al igual que el import en los scripts de Ant, el import en Spring es conveniente para unir archivos modularizados de comfiguración. Por ejemplo:

<beans>

       <import resource="InvasorServices.xml"/>
       <import resource="RobotsServices.xml"/>
       <bean id="PlanetaObjetivoService" 
             class="com.dosideas.spring.PlanetaObjetivoService"/>

<beans>

En vez de unirlos dentro del XML utilizando imports, es mucho mas flexible configurarlo a traves del ApplicationContext. Utilizando ApplicationContext tambien hace que nuestra configuración XML sea mas facil de manejar. Se le puede pasar como argumento al constructor de ApplicationContext una lista de archivos de configuración. Nuestro ejemplo anterior quedaria:

String[] serviceResources =

       {"PlanetaServices.xml",
       "InvasorServices.xml",
       "RobotServices.xml"};

ApplicationContext orderServiceContext = new

       ClassPathXmlApplicationContext(serviceResources);