INT-1903 polishing

This commit is contained in:
Oleg Zhurakousky
2011-05-16 16:57:13 -04:00
parent 5bf5d1f145
commit 0cb3c14603
5 changed files with 132 additions and 36 deletions

View File

@@ -22,33 +22,48 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationContextEvent;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.integration.MessageHeaders;
import org.springframework.integration.MessageHeaders.IdGenerator;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
* @author Oleg Zhurakousky
* @since 2.0.4
*/
public final class IdGeneratorConfigurer implements ApplicationListener<ContextRefreshedEvent>, DisposableBean {
public final class IdGeneratorConfigurer implements ApplicationListener<ApplicationContextEvent>{
private final Log logger = LogFactory.getLog(getClass());
private volatile String generatorContextId;
public void onApplicationEvent(ContextRefreshedEvent event) {
this.setIdGenerator(event.getApplicationContext());
public void onApplicationEvent(ApplicationContextEvent event) {
if (event instanceof ContextRefreshedEvent){
if (!StringUtils.hasText(generatorContextId)){
ApplicationContext contex = event.getApplicationContext();
if (this.setIdGenerator(contex)){
this.generatorContextId = contex.getId();
}
}
}
else if (event instanceof ContextClosedEvent){
ApplicationContext contex = event.getApplicationContext();
if (contex.getId().equals(generatorContextId)){
this.unsetIdGenerator();
this.generatorContextId = null;
}
}
}
public void destroy() throws Exception {
this.unsetIdGenerator();
}
private void setIdGenerator(ApplicationContext context) {
private boolean setIdGenerator(ApplicationContext context) {
try {
IdGenerator idGeneratorBean = context.getBean(IdGenerator.class);
if (logger.isDebugEnabled()) {
@@ -56,11 +71,11 @@ public final class IdGeneratorConfigurer implements ApplicationListener<ContextR
}
Field idGeneratorField = ReflectionUtils.findField(MessageHeaders.class, "idGenerator");
ReflectionUtils.makeAccessible(idGeneratorField);
IdGenerator existingIdGenerator = (IdGenerator) ReflectionUtils.getField(idGeneratorField, null);
if (existingIdGenerator != null) {
throw new BeanDefinitionStoreException(
"'MessageHeaders.idGenerator' has already been set and can not be set again");
}
// IdGenerator existingIdGenerator = (IdGenerator) ReflectionUtils.getField(idGeneratorField, null);
// if (existingIdGenerator != null) {
// throw new BeanDefinitionStoreException(
// "'MessageHeaders.idGenerator' has already been set and can not be set again");
// }
if (logger.isInfoEnabled()) {
logger.info("Message IDs will be generated using custom IdGenerator [" + idGeneratorBean.getClass() + "]");
}
@@ -75,13 +90,16 @@ public final class IdGeneratorConfigurer implements ApplicationListener<ContextR
if (logger.isDebugEnabled()) {
logger.debug("Unable to locate MessageHeaders.IdGenerator. Will use default: UUID.randomUUID()");
}
return false;
}
catch (IllegalStateException e) {
if (logger.isWarnEnabled()) {
logger.warn("Unexpected exception occurred while accessing idGenerator of MessageHeaders." +
" Will use default: UUID.randomUUID()", e);
}
return false;
}
return true;
}
private void unsetIdGenerator() {

View File

@@ -35,19 +35,25 @@ import org.springframework.util.StringUtils;
public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutboundChannelAdapterParser {
protected String parseAndRegisterConsumer(Element element, ParserContext parserContext) {
BeanComponentDefinition consumerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
String consumerRef = null;
if (consumerDefinition == null){
consumerRef = element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE);
} else {
consumerRef = consumerDefinition.getBeanName();
}
if (element.hasAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE)) {
consumerRef = BeanDefinitionReaderUtils.registerWithGeneratedName(
this.parseConsumer(element, parserContext), parserContext.getRegistry());
}
Assert.hasText(consumerRef, "Can not determine consumer for 'outbound-channel-adapter'");
return consumerRef;
AbstractBeanDefinition consumerDefinition = this.parseConsumer(element, parserContext);
// if (element.hasAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE)){
// consumerDefinition = this.parseConsumer(element, parserContext);
// }
//
//
// BeanComponentDefinition consumerDefinition = IntegrationNamespaceUtils.parseInnerHandlerDefinition(element, parserContext);
// String consumerRef = null;
// if (consumerDefinition == null){
// consumerRef = element.getAttribute(IntegrationNamespaceUtils.REF_ATTRIBUTE);
// } else {
// consumerRef = consumerDefinition.getBeanName();
// }
// if (element.hasAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE)) {
// consumerRef = this.parseConsumer(element, parserContext);
// }
// Assert.hasText(consumerRef, "Can not determine consumer for 'outbound-channel-adapter'");
String consumerName = BeanDefinitionReaderUtils.registerWithGeneratedName(consumerDefinition, parserContext.getRegistry());
return consumerName;
}
@Override
@@ -66,7 +72,10 @@ public class MethodInvokingOutboundChannelAdapterParser extends AbstractOutbound
} else {
invokerBuilder.addConstructorArgValue(innerHandlerDefinition);
}
invokerBuilder.addConstructorArgValue(element.getAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE));
String methodName = element.getAttribute(IntegrationNamespaceUtils.METHOD_ATTRIBUTE);
if (StringUtils.hasText(methodName)){
invokerBuilder.addConstructorArgValue(methodName);
}
String order = element.getAttribute(IntegrationNamespaceUtils.ORDER);
if (StringUtils.hasText(order)) {
invokerBuilder.addPropertyValue(IntegrationNamespaceUtils.ORDER, order);

View File

@@ -20,6 +20,7 @@ import java.lang.reflect.Method;
import org.springframework.integration.Message;
import org.springframework.integration.MessagingException;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.core.MessageHandler;
import org.springframework.util.Assert;
@@ -45,6 +46,10 @@ public class MethodInvokingMessageHandler extends AbstractMessageHandler {
processor = new MethodInvokingMessageProcessor<Object>(object, methodName);
}
public MethodInvokingMessageHandler(Object object) {
processor = new MethodInvokingMessageProcessor<Object>(object, ServiceActivator.class);
}
public void setComponentType(String componentType) {
this.componentType = componentType;

View File

@@ -5,11 +5,11 @@
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration-2.0.xsd">
<bean id="idGenerator" class="org.mockito.Mockito" factory-method="spy">
<constructor-arg>
<bean class="org.springframework.integration.core.MessageIdGenerationTests.SampleIdGenerator"/>
</constructor-arg>
</bean>
<!-- <bean id="idGenerator" class="org.mockito.Mockito" factory-method="spy"> -->
<!-- <constructor-arg> -->
<!-- <bean class="org.springframework.integration.core.MessageIdGenerationTests.SampleIdGenerator"/> -->
<!-- </constructor-arg> -->
<!-- </bean> -->
<int:channel id="input"/>

View File

@@ -25,6 +25,7 @@ import java.util.UUID;
import org.junit.Ignore;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.integration.MessageChannel;
import org.springframework.integration.MessageHeaders;
@@ -39,19 +40,69 @@ import org.springframework.util.StopWatch;
*/
public class MessageIdGenerationTests {
@Test
public void testCustomIdGeneration(){
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
public void testCustomIdGenerationWithParentRegistrar(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context-a.xml", this.getClass());
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context.xml"}, this.getClass(), ctx);
IdGenerator idGenerator = context.getBean("idGenerator", IdGenerator.class);
MessageChannel inputChannel = context.getBean("input", MessageChannel.class);
inputChannel.send(new GenericMessage<Integer>(0));
verify(idGenerator, times(4)).generateId();
reset(idGenerator);
context.destroy();
context.close();
new GenericMessage<Integer>(0);
verify(idGenerator, times(1)).generateId();
}
@Test
public void testCustomIdGenerationWithParentRegistrarClosed(){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context-a.xml", this.getClass());
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context.xml"}, this.getClass(), ctx);
IdGenerator idGenerator = context.getBean("idGenerator", IdGenerator.class);
MessageChannel inputChannel = context.getBean("input", MessageChannel.class);
inputChannel.send(new GenericMessage<Integer>(0));
verify(idGenerator, times(4)).generateId();
reset(idGenerator);
ctx.close();
new GenericMessage<Integer>(0);
verify(idGenerator, times(0)).generateId();
}
@Test
public void testCustomIdGenerationWithChildRegistrar(){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context-a.xml"}, this.getClass(), ctx);
IdGenerator idGenerator = context.getBean("idGenerator", IdGenerator.class);
MessageChannel inputChannel = context.getBean("input", MessageChannel.class);
inputChannel.send(new GenericMessage<Integer>(0));
verify(idGenerator, times(4)).generateId();
reset(idGenerator);
ctx.close();
new GenericMessage<Integer>(0);
verify(idGenerator, times(1)).generateId();
}
@Test
public void testCustomIdGenerationWithChildRegistrarClosed(){
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("MessageIdGenerationTests-context.xml", this.getClass());
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[]{"MessageIdGenerationTests-context-a.xml"}, this.getClass(), ctx);
IdGenerator idGenerator = context.getBean("idGenerator", IdGenerator.class);
MessageChannel inputChannel = context.getBean("input", MessageChannel.class);
inputChannel.send(new GenericMessage<Integer>(0));
verify(idGenerator, times(4)).generateId();
reset(idGenerator);
context.close();
new GenericMessage<Integer>(0);
verify(idGenerator, times(0)).generateId();
}
@Test
@Ignore
public void performanceTest(){
@@ -91,6 +142,19 @@ public class MessageIdGenerationTests {
public static class SampleIdGenerator implements IdGenerator {
public SampleIdGenerator(){
System.out.println("Generator");
}
public UUID generateId() {
return UUID.nameUUIDFromBytes(((System.currentTimeMillis() - System.nanoTime()) + "").getBytes());
}
}
public static class SampleIdGeneratorA implements IdGenerator {
public SampleIdGeneratorA(){
System.out.println("Generator A");
}
public UUID generateId() {
return UUID.nameUUIDFromBytes(((System.currentTimeMillis() - System.nanoTime()) + "").getBytes());