SyntaxHighlighter

Showing posts with label SpEL. Show all posts
Showing posts with label SpEL. Show all posts

Thursday, May 30, 2013

Spring Integration - Calling a Service based on a Header Value

Spring Integration - Calling a Service based on a Header Value


here's a situation you may have encountered in Spring Integration, based on a header value, you want to invoke a certain service.  but, you've got a whole bunch of the services and putting in a header value router with an endpoint for each one is a bit of a pain, especially if they all inherit from the same Interface.

so, here's a quick solution to simplify your Spring Integration configuration;

here's the XML,



 
 
 
  
 

 
 
 
 
  

 




here's our wrapper bean - it's responsible for exposing the BeanFactory


package de.incompleteco.spring.context;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

public class BeanFactoryWrapper implements BeanFactoryAware {

 private org.springframework.beans.factory.support.DefaultListableBeanFactory beanFactory;
 
 public Object getBean(String name) throws BeansException {
  return beanFactory.getBean(name);
 }

 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  this.beanFactory = (DefaultListableBeanFactory) beanFactory;
 }

}

and finally, a simple test to see if it works

package de.incompleteco.spring.integration;

import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.integration.Message;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.support.MessageBuilder;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import de.incompleteco.spring.integration.service.ASomeService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:/META-INF/spring/*-context.xml"})
public class ContextIntegrationTest {

 @Autowired
 @Qualifier("input.channel")
 private DirectChannel channel;
 
 @Autowired
 private ASomeService aSomeService;
 
 @Test
 public void test() throws Exception {
  assertNull(aSomeService.getPayload());
  //create a message with the header
  Message instruction = MessageBuilder.withPayload("hello world").setHeader("serviceName", "aSomeService").build();
  //send
  channel.send(instruction);
  //wait
  Thread.sleep(100);
  //now check 
  assertNotNull(aSomeService.getPayload());
 }
 
}

Thursday, September 13, 2012

SpEL and Returning an Object From Void

SpEL and Returning an Object From Void

an odd scenario encountered at the client; they wanted to use a service via a service-activator in Spring Integration but use the exception and void as the true/false.  that is, the service validated an object and returned 'void' (nothing) if it was ok, and threw and exception if it was not.  but, in the Spring Integration pattern, they wanted the object to continue on after invoking the service-activator.  this pattern wouldn't normally work as a void in a service-activator doesn't return the object, and the message flow dies.  so, how to do it?

well, thanks to some insight from a colleague, this is the SpEL-based solution we came up with...


as you can see, using SpEL in the if/else allowed the return of the existing 'untouched' payload.  an exception, if thrown, can be handled via Spring Integration's normal patterns.

Friday, August 24, 2012

@Value injection and Spring Data JPA extensions

@Value injection

a neat little Spring feature is the @Value annotation.  this allows you to directly inject string values and other neat pieces from properties files or other SpEL accessible functions.

a scenario where it is particularly useful is when using customization/extensions to Spring Data JPA.  in particular, i'm going to create a class that requires native sql functions as part of Spring Data JPA.  i want to be able to leverage as much of Spring Data JPA as possible, and the native functions are different from platform to platform (dontcha love sql?).  to assist with this, i can create my implementation class with the particular SQL statement injected using the @Value annotation

so, for the code, here's the entity



here's the custom dao interface



here's the normal Spring Data JPA interface



note: notice the interface extends the custom one.

here's the implementation, including the @Value annotation



and here's how we wire it together



notice the use of the properties placeholder that maps directly to the @Value annotation