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:
Filed under: puzzlers, spring | 1 Comentario

Sincerely, I have no idea.
But I’ve had a lot of fun trying to discover the solution.
At the end, I’ve just copy-paste the code in order to see it running.
Before doing that, I read the javadoc for the Spring classes involved, and I could discard some answers. While I was copying the code, I saw something weird that gave me a clue for the right answer.
But honestly, I didn’t know the solution until I saw the code running.
Thanks a lot for giving some fun to us, as well as a good source for learning.