Spring Puzzlers #02: The Happy Traveler

I really love traveling, and even more when I don’t know what my next destination will be. That’s one of my biggest passions, I have to admit it. If you also love traveling, you should consider using my TravelService for your next trip. Let me introduce you the second Spring Puzzler:

The TravelService will be our entry point. It has a method to print a destination picked by a DestinationPicker (shown below). Notice that the method is annotated with @Async to run it asynchronously in another thread:

public class TravelServiceImpl implements TravelService {
	private Logger logger = Logger.getLogger(TravelServiceImpl.class);
	
	private DestinationPicker destinationPicker;
	
	@Async
	public void printNextDestination() {
		logger.info("Running from thread: " + Thread.currentThread().getId());
		
		System.out.println("Your next holiday destination: " + 
							destinationPicker.getDestination());
	}

	public void setDestinationPicker(DestinationPicker destinationPicker) {
		this.destinationPicker = destinationPicker;
	}
}

This is the RandomDestinationPicker, which uses a really complex algorithm to choose the destination from a list of available destinations :). It uses the id field (increased in every object creation) to determine the location:

public class RandomDestinationPicker implements DestinationPicker {
	
	private static int instances = 0;
	
	private int id;
	private List<String> availableDestinations;	
	
	public RandomDestinationPicker(List<String> availableDestinations) {
		this.availableDestinations = availableDestinations;
		id = instances++;
	}
	
	public String getDestination() {
		return availableDestinations.get(id % availableDestinations.size());
	}
}

The next XML file has the configuration for our Application Context:
– It defines a list of destinations (a list of strings)
– It defines the DestinationPicker injecting the list of available destination and setting the scope of the bean to ‘puzzle’.
– It defines the TravelService injecting the DestinationPicker.
– It enables the @Async annotation (task:annotation-driven)
– It defines a new scope called ‘puzzle’ which is a thread scope

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:task="http://www.springframework.org/schema/task"
	xmlns:p="http://www.springframework.org/schema/p"
	xmlns:util="http://www.springframework.org/schema/util"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
		http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">


	<bean id="travelService" class="com.sergialmar.springpuzzlers.sp02.TravelServiceImpl" 
							 p:destinationPicker-ref="destinationPicker"/>

	<bean id="destinationPicker" class="com.sergialmar.springpuzzlers.sp02.RandomDestinationPicker" 
								  scope="puzzle">
		<constructor-arg ref="destinationList"/>
	</bean>
								  
	<util:list id="destinationList">
		<value>San Francisco</value>
		<value>Kuala Lumpur</value>
		<value>Barcelona</value>
		<value>Mexico City</value>
		<value>Cape Town</value>
	</util:list>
	
	<task:annotation-driven/>

	<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
      <property name="scopes">
          <map>
              <entry key="puzzle">
                  <bean class="org.springframework.context.support.SimpleThreadScope"/>
              </entry>
          </map>
      </property>
  	</bean>
</beans>

The bootstrap class creates the application context and gets the TravelService bean, calling the printNextDestination method 4 times.

public class TravelBootstrap {

	public static void main(String... args) {
		ApplicationContext applicationContext = 
			new ClassPathXmlApplicationContext("com/sergialmar/springpuzzlers/sp02/app-context.xml");
		
		TravelService travelService = 
			applicationContext.getBean(TravelService.class);
		
		travelService.printNextDestination();
		travelService.printNextDestination();
		travelService.printNextDestination();
		travelService.printNextDestination();
	}
}

Time to vote! Which of the following statements is right:

Spring Puzzler #01: Welcome

I’ve spent the last two years and a half delivering the official SpringSource courses all over the world and during this time I’ve seen a lot of students coming across unexpected behaviors and wondering why. Based on Josh Bloch’s Java Puzzlers, I’m going to introduce you the Spring Puzzlers, a bunch of puzzlers ranging from Spring configuration gotchas to AOP and dynamic proxy voodoo, transactional enigmas…

So here’s the first one 🙂

Our entry point will be a WelcomeService, a really simple interface with a single method welcome:

public interface WelcomeService {
	void welcome(String name);
}

The implementation uses a LocalizedWelcomePrinter to print the localized message to the console. I’ll be using JSR-330 annotations for the DI :

import javax.inject.Inject;
import javax.inject.Named;

@Named
public class ConsoleWelcomeService implements WelcomeService {

	@Inject
	private static LocalizedWelcomePrinter printer = new SpanishWelcomePrinter();

	public void welcome(String name) {
		printer.printWelcome(name);
	}

}

There are 2 implementations of the LocalizedWelcomePrinter (a custom interface), one for Spanish:

public class SpanishWelcomePrinter implements LocalizedWelcomePrinter {

	public void printWelcome(String name) {
		System.out.println("Bienvenido a Spring Puzzlers " + name);
	}

}

And one for English. Notice I’m using @Named here to autoregister the component in the application context:

@Named
public class EnglishWelcomePrinter implements LocalizedWelcomePrinter {

	public void printWelcome(String name) {
		System.out.println("Welcome to Spring Puzzlers " + name);
	}
}

So the configuration is quite straightforward, a single line enabling the component scanning:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
		
	<context:component-scan base-package="com.sergialmar.springpuzzlers" />

</beans>

And this is the class that bootstraps the system:

public class WelcomeBootstrap {

	public static void main(String... args) {
		ApplicationContext applicationContext =
			new ClassPathXmlApplicationContext("app-context.xml");

		WelcomeService welcomeService =
			applicationContext.getBean(WelcomeService.class);

		welcomeService.welcome("Sergi");
	}
}

So…what will be the output after running this class? Choose the right answer from the below poll!

Configuración basada en anotaciones y el Spring Explorer

Uno de los “problemas” que tiene asociada la configuración basada en anotaciones en Spring es que tenemos nuestra configuración distribuida en nuestros componentes (tenemos disponibles anotaciones como @Controller, @Service, @Repository, @Component, @Autowired…) cuando con XML podemos tenerla centralizada y puede ser más fácil tener la visión a primera vista.

Si nos centramos en la capa web, si configuramos nuestros controladores con la anotación @Controller y los mappings de las URLs con la anotación @RequestMapping, vamos a tener todas nuestras URLs a procesar repartidas en todos nuestros controladores, con lo que será más difícil saber quien es el responsable de procesar una cierta URL.

Para ello, os recomiendo usar la vista Spring Explorer de SpringSource Tool Suite, que nos dará la información que necesitamos, en este caso respeto a los mapeos y las clases configuradas con anotaciones.

Hands-on Spring 3: The next generation (SOCF)

Dejo aquí mi presentación del taller “Hands-on Spring 3: The next generation” impartido en el Sun Open Communities Forum (18 de Junio 2009):

Los proyectos de ejemplo de SpringSource Tool Suite los podeis encontrar aquí.

Update 25/06/09:

Poco tiempo para postear durante el evento, así que sólo me dio tiempo para colgar la presentación y el ejemplo.El evento fue otra excusa para retomar contacto con gente como Abraham Otero, Alfredo Casado, Nacho Brito, Nacho Coloma, Dani López, Dani Latorre, Álvaro Sanchez-Mariscal, Peyrona…De hecho mi impresión es que en España, en general, hay poca filosofía de asistir a eventos como este, los asistentes totales fueron 164, que si comparamos con otros eventos como Devoxx (otra índole está claro) que hacen lleno con 3200 asistentes, queda com un poco ridículo. Aunque la magnitud del evento no es comparable, a lo que me refiero, es que aún siendo eventos gratuitos (Devoxx requiere entrada), no veo una gran aceptación a este tipo de iniciativas como la tienen en otros sitios fuera de España. Me pregunto porqué…

Por otra parte, os dejo arriba, el ejemplo que hice para el taller de Spring 3.0. Encontrareis la versión acabada y la versión por acabar. Consiste en un javaHispano REST, donde se debe completar algunas partes de soporte para peticiones REST (GET y DELETE), negociación de contenido (MarshallingView para mostrar noticias en XML) y consumo de servicios REST (parte cliente), en este caso consumo de los servicios REST de Flickr.

Sun Open Communities Forum 09 (Taller Sergi)

Un pasito adelante hacia Spring 3.0

La verdad es que se está haciendo larga la espera de esta versión mayor. En diciembre del año pasado, en Devoxx, se dio a conocer el roadmap de Spring 3.0:

Spring 3.0 Milestones Enero/Febrero 2009
Spring 3.0 Release Candidates Marzo/Abril 2009

Hoy mismo se ha dado a conocer la tercera milestone de Spring 3.0 (Mayo) y la RC1 está anunciada para Junio 09. La demora sigue….y ya hace un año y medio del anuncio de Spring 2.5. Toca esperar…

Pero, que nos espera en esta versión?

  • Spring Expression Language: Un lenguaje de expresiones con sintaxis similar a Unified EL con funcionalidades adicionales como invocaciones de métodos. Se podrá utilizar en configuraciones XML o mediante anotaciones. Un ejemplo:
    <bean class="mycompany.RewardsTestDatabase">
    <property name="databaseName"
            value="#{systemProperties.databaseName}"/>
    <property name="keyGenerator"
            value="#{strategyBean.databaseKeyGenerator}"/>
    </bean>
    
    

    En el caso de las anotaciones:

    @Repository
    public class RewardsTestDatabase {
        @Value("#{systemProperties.databaseName}")
        public void setDatabaseName(String dbName) { ... }
        @Value("#{strategyBean.databaseKeyGenerator}")
        public voidsetKeyGenerator(KeyGenerator kg) { ... }
    }
    
    
  • Metadatos para configuración: Algunas de las funcionalidades de JavaConfig se han incluido en Spring Framework. De esta manera, anotaciones como @Configuration @Bean @Primary @Lazy @Import o @Value, van a ser accesibles directamente. Esto nos va a permitir definir nuestros beans en clases anotadas (podemos decir que un método anotado con @Bean va a registrar un bean en nuestro aplication context del tipo especificado por el valor de retorno teniendo así comportamiento de BeanFactory) . Ejemplo:
    @Configuration
    public class AppConfig {
        @Bean
        public TransferService transferService() {
            return new TransferServiceImpl();
        }
    }
    

    Que va a ser el equivalente a:

    <beans>
        <bean name="transferService" class="com.acme.TransferServiceImpl"/>
    </beans>
    

    Not my style, pero para gustos colores…

  • Soporte extendido para metaanotaciones: anotaciones como @Scope @Transactional  @Service  @Controller puedes ser utilizadas como metaanotaciones lo que nos va a permitir crear nuestras anotaciones con estos comportamientos. Ejemplo:
    @Service
    @Scope("request")
    @Transactional(rollbackFor=Exception.class)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface MiServicio {
    }
    
    @MiServicio
    public class RewardsService {…}
    
  • OXM: El soporte para marshalling/unmarshalling de XML usando OXMs que se encontraba en Spring Web Services, pasa a ser parte de Spring Framework.
  • Soporte para REST: sin duda la mejor funcionalidad significativa en esta versión. Extiende Spring @MVC para soportar aplicaciones RESTful. En el caso de tener una URL con patrón http://www.example.com/owners/{ownerId}, podremos definir:
    @RequestMapping("/owners/{ownerId}", method=RequestMethod.GET)
    public String findOwner(@PathVariable String ownerId, Model model) {
      Owner owner = ownerService.findOwner(ownerId);
      model.addAttribute("owner", owner);
      return "displayOwner";
    }
    
  • Más anotaciones para Spring @MVC: Se han añadido @CookieValue y @RequestHeaders a la lista.
  • Abstracción para TaskScheduler: Spring provee ahora una facade scheduling API. En la próxima RC van a incorporar un namespace para scheduling.
  • Y cosas pendientes: Hibernate Validator, JEE 6 (JSF 2, JPA2…).

En los próximos días estaré enredando un poco con las nuevas funcionalidades…

Primer curso Core Spring realizado

Después de anunciar el partnership con SpringSource, la semana pasada impartí el primer curso en España (Madrid) junto a David Gómez (compañero de Extrema) y Ben Corrie (consultor de SpringSource).

Primer curso Core Spring (Madrid)

El curso se llenó con 15 personas (normalmente van a ser un máximo de 12 personas) procedentes de diferentes partes: Madrid, Valencia, Tenerife, San Sebastián, Asturias y Huesca. Next stop Barcelona!

También aproveche para quedar con Abraham y poder charlar un breve rato sobre diferentes temas de javaHispano, siempre un placer coincidir cuando los integrantes estamos tan repartidos geográficamente.

SpringSource Certified Spring Professional

Recientemente SpringSource ha sacado lo que ha llamado Spring University, dando acceso a tres certificaciones (solo una disponible por el momento). Hoy me he decidido a realizar la certificación SpringSource Certified Spring  Professional, obteniéndola con un 88%.

SpringSource Certified Spring Professional

La verdad es que me esperaba un examen un poco más fácil y más balanceado. Me explico: el examen consiste en 50 preguntas multirespuesta (creo que solo han salido 3 multirespuesta, las otras eran de respuesta simple pero con las opciones típicas: Todas las anteriores, Ninguna de las anteriores, La a y la b son correctas…) a contestar en un tiempo de 90 minutos; el problema es que el peso de cada tema, no se corresponde porcentualmente con las preguntas. Mi impresión es que en el examen los dos temas más fuertes han sido JMS y JMX (también podría destacar 3 preguntas de remoting referentes a Hessian / Burlap), con lo que no creo que haga justicia a evaluar lo que realmente tiene más importancia. Esta es una cuestión que están intentando arreglar; por lo que se ve, las preguntas se seleccionan de un pool al azar, dando la posibilidad  que salgan más preguntas de JMS que de el propio contenedor de beans o AOP.

Las personas certificadas disponen de un grupo en LinkedIn, donde a día de hoy hay registradas 71 personas (a escala mundial). Este bajo número me hace pensar en lo diferenciador que hace tener una de estas certificaciones teniendo en cuenta el panorama actual en que la tendencia de demanda de profesionales en Spring sigue en ascenso. El único requisito para poder realizar la certificación es asistir a un curso oficial de SpringSource o bien ser considerado un candidato “grandfathered”. En España se van a empezar a impartir cursos en breve (Madrid, Barcelona), así que os animo a ser uno de los primeros en obtener la certificación en nuestro territorio 😉