Spring 3 Java Config Style

3
18691

Spring 3 Java Config Style

Introducción

Creo que a estas alturas a nadie le voy a descubrir el framework de Spring y lo que ha aportado
a la comunidad Java/JEE sin pedir nada a cambio.

No obstante, es probable que las novedades de Spring 3 se nos hayan escapado, y es por eso que he decidido hacer una serie de
tutoriales comentando algunas de ellas.

Configuración de Spring

Antes de la versión 2.5 la única manera de configurar el contenedor de Spring era a través de ficheros XML.
Esta manera, que es por otro lado suficiente, a veces se puede convertir en un engorro al proliferar el número de «Beans» de nuestros proyectos.
Tras la aparición de las anotaciones en Java 1.5, Spring introdujo la posibilidad de configurar el contexto también a
través de éstas o combinando ambas. Yo suelo utilizar anotaciones para mis clases (las de mi proyecto)
y XML para las clases externas (no había más remedio, ya que no se «puede» anotar el código que no es mío)

A partir de Spring 3.0 aparece una nueva manera de configurar el contexto al estilo JavaConfig:

Configuración del contenedor con Java

Esta nueva forma de configurar el contenedor está basada principalmente en dos nuevas anotaciones y en una nueva implementación de ApplicationContext:

  • @Configuration: Usar una anotación de este tipo en una clase sirve para indicarle a Spring que ésta es una clase contenedora
    de definiciones de «Beans». Es importante hacer notar que una clase anotada con @Configuration será también registrada como «bean», y por lo tanto
    también podremos usar las anotaciones de inyección de dependencias (@Autowired, @Inject o @Resource)
  • @Bean: Anotar un método de esta manera es equivalente a usar <bean> en un fichero de configuración tradicional de Spring.
    Además no es imprescindible para poder usar esta anotación que la clase sea anotada con @Configuration, sino que también serán
    «entendidas» aquellas que aparezcan en otras clases @Component (y por ende @Service, @Repository o @Controller)
  • AnnotationConfigApplicationContext: Esta clase será la encargada de levantar el contexto de Spring y entiende no sólo las anotaciones
    tradicionales sino también las dos anteriores.

En el ejemplo que se muestra a continuación se muestran dos ejemplos de configuración que son equivalentes:
Estilo «Cocina tradicional»:



  
  
  
	
	    
	
	
		
	

Este es el dao.xml importado previamente:



  
  
		
		
		
		
	

Estilo «Nouvelle cuisine»:

@Configuration
// Esta anotación es equivalente al import de xml
@Import({DataSourceConfig.class})
public class SpringJavaConfigStyle {
	
	
	@Autowired
	private DataSource dataSource;
	
	@Bean	
	public A beanA() {
		return new A(dataSource);
	}
  	
	@Bean
  public B beanB() {
    return new B(beanA());
  }

}
@Configuration
public class DataSourceConfig {
	
		
	@Bean	
	public DataSource dataSource() {
		
		Properties props = new Properties();
			// Configuración de las propiedades
			// ...
		return new DriverManagerDataSource("XXX",props);
				
	}

}

Para levantar el contexto:

...
  public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringJavaConfigStyle.class);
    B b = ctx.getBean("beanB", B.class);    
    ...    
}
...

Otra opción equivalente para la inyección de dependencias, sería:

@Configuration
@Import({DataSourceConfig.class})
public class SpringJavaConfigStyle {
	
	
	@Autowired
	private DataSourceConfig dataSourceConfig;
	
	@Bean	
	public A beanA() {
		return new A(dataSourceConfig.dataSource());
	}
  	
	@Bean
  public B beanB() {
    return new B(beanA());
  }

}

Por otro lado, la anotación @Bean recibe diversos parámetros para configurar los nombres del «Bean»,
los métodos del ciclo de vida (init y destroy), y si queremos usar autowire en las propiedades del «Bean».
Usar el método «init» no tiene ya demasiado sentido porque se puede realizar después de la instanciación.
Además si queremos modificar el ámbito del «Bean», bastaría con usar la anotación @Scope:

@Configuration
@Import({DataSourceConfig.class})
public class SpringJavaConfigStyle {
	
	
	@Autowired
	private DataSourceConfig dataSourceConfig;
	
	@Bean	
	public A beanA() {
		return new A(dataSourceConfig.dataSource());
	}
  	
	@Bean(name = { "beanB", "mrBean"})
	@Scope("protoype")
  public B beanB() {
    return new B(beanA());
  }

}

Mezclando XML y JavaConfig

Debido a que el estilo JavaConfig no es capaz de reemplazar completamente al estilo XML (principalmente por el tema de los namespaces),
conviene utilizar una combinación de ambas. Para poder hacer esto, como todo en Spring tenemos varias opciones, más en concreto dos:

El XML «manda»:

En este caso, usaremos una de las versiones de «XmlApplicationContext» y la cargaremos al estilo tradicional.
Pero para poder activar en este caso la búsqueda de anotaciones de configuración es necesario incluir:



     
      
     
     
     
     

Si nos queremos ahorrar la definición de los beans de configuración en el XML:



     
      
     
      
     
      
     

JavaConfig «manda»:

En este caso, debemos utilizar el mecanismo que hemos contado en los apartados anteriores (usando AnnotationConfigApplicationContext)
y utilizar la anotación @ImportResource:

@Configuration
@Import({DataSourceConfig.class})
@ImportResource("classpath:appContext.xml")
public class SpringJavaConfigStyle {
	
	
	@Autowired
	private DataSourceConfig dataSourceConfig;
	
	@Bean	
	public A beanA() {
		return new A(dataSourceConfig.dataSource());
	}
  	
	@Bean(name = { "beanB", "mrBean"})
	@Scope("protoype")
  public B beanB() {
    return new B(beanA());
  }
}

Carga del contexto vía JavaConfig en aplicaciones Web

Spring suele pensar en todo, y tal como se hacía para cargar el contexto de Spring en aplicaciones Web con XML, tenemos la versión
«JavaConfig manda» para cargar el contexto en aplicaciones Web. A continuación se muestra un ejemplo:



  
  
  
    contextClass
    
      org.springframework.web.context.support.AnnotationConfigWebApplicationContext
    
  
  
  
    contextConfigLocation
    com.autentia.tutoriales.config.SpringJavaConfigStyle
  
    
  
    org.springframework.web.context.ContextLoaderListener
  
  
  

Conclusiones:

La flexibilidad de la configuración del contexto de Spring queda sin ninguna duda completada con este
modelo nuevo basado en Java. Pero lo mejor de todo es la posibilidad de combinar las tres maneras de
configuración aportadas por Spring. Sabiendo las ventajas y los inconvenientes de cada una de ellas
podemos elegir la que mejor se adecúe a cada proyecto y a cada caso en particular:

Configuración XML

La configuración basada en XML es la más conveniente para configurar «beans» de infraestructura (DataSources, acceso a servicios…)


Ventajas:

  • Configuración centralizada en uno o varios ficheros.
  • Aplicable a todas las clases (nuestras y externas).
  • De alguna manera, ya estamos familiarizados con esta forma de configuración.

Desventajas:

  • Los ficheros se pueden volver algo engorrosos.
  • Hay gente que «odia» el XML.

Configuración por Anotaciones

La configuración basada en anotaciones es ideal para «beans» muy cambiantes (controladores…)


Ventajas:

  • Permite un desarrollo muy rápido.
  • Todo está en la misma clase.

Desventajas:

  • Evidentemente sólo podemos aplicarlo sobre nuestras clases.
  • Podemos perder de vista la configuración al estar distribuida por todo nuestro código.

Configuración por JavaConfig

Este mecanismo proporciona un control total sobre la creación de Beans y configuración de los mismos.


Ventajas:

  • Mayor velocidad en la carga del contexto.
  • Gran flexibilidad ya que puede ser usada en todas las clases.

Desventajas:

  • EL plugin de Spring (Spring Tool Suite) no puede representar la configuración de este tipo.

3 COMENTARIOS

DEJA UNA RESPUESTA

Por favor ingrese su comentario!

He leído y acepto la política de privacidad

Por favor ingrese su nombre aquí

Información básica acerca de la protección de datos

  • Responsable:
  • Finalidad:
  • Legitimación:
  • Destinatarios:
  • Derechos:
  • Más información: Puedes ampliar información acerca de la protección de datos en el siguiente enlace:política de privacidad