diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java index 9fdf18cd97..7260b99d36 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/CorrelationStrategyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2010 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.integration.config; import java.lang.reflect.Method; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; import org.springframework.integration.IntegrationMessageHeaderAccessor; import org.springframework.integration.aggregator.CorrelationStrategy; import org.springframework.integration.aggregator.HeaderAttributeCorrelationStrategy; @@ -26,52 +27,81 @@ import org.springframework.integration.util.MessagingAnnotationUtils; import org.springframework.util.StringUtils; /** - * Convenience factory for XML configuration of a {@link CorrelationStrategy}. Encapsulates the knowledge of the default - * strategy and search algorithms for POJO and annotated methods. + * Convenience factory for XML configuration of a {@link CorrelationStrategy}. + * Encapsulates the knowledge of the default strategy and search algorithms for POJO and annotated methods. * * @author Dave Syer + * @author Artem Bilan * */ -public class CorrelationStrategyFactoryBean implements FactoryBean { +public class CorrelationStrategyFactoryBean implements FactoryBean, InitializingBean { - private CorrelationStrategy delegate = new HeaderAttributeCorrelationStrategy(IntegrationMessageHeaderAccessor.CORRELATION_ID); + private Object target; - /** - * Create a factory and set up the delegate which clients of the factory will see as its product. - * - * @param target the target object (null if default strategy is acceptable) - */ - public CorrelationStrategyFactoryBean(Object target) { - this(target, null); + private String methodName; + + private CorrelationStrategy strategy = + new HeaderAttributeCorrelationStrategy(IntegrationMessageHeaderAccessor.CORRELATION_ID); + + public CorrelationStrategyFactoryBean() { } /** - * Create a factory and set up the delegate which clients of the factory will see as its product. - * + * Create a factory and set up the strategy which clients of the factory will see as its product. + * @param target the target object (null if default strategy is acceptable) + * @deprecated since {@literal 4.2.5} in favor of appropriate setters + * to avoid {@code BeanCurrentlyInCreationException} + * during {@code AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck()} + */ + @Deprecated + public CorrelationStrategyFactoryBean(Object target) { + this.target = target; + } + + /** + * Create a factory and set up the strategy which clients of the factory will see as its product. * @param target the target object (null if default strategy is acceptable) * @param methodName the method name to invoke in the target (null if it can be inferred) + * @deprecated since {@literal 4.2.5} in favor of appropriate setters + * to avoid {@code BeanCurrentlyInCreationException} + * during {@code AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck()} */ + @Deprecated public CorrelationStrategyFactoryBean(Object target, String methodName) { - if (target instanceof CorrelationStrategy && !StringUtils.hasText(methodName)) { - delegate = (CorrelationStrategy) target; + this.target = target; + this.methodName = methodName; + } + + public void setTarget(Object target) { + this.target = target; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + @Override + public void afterPropertiesSet() throws Exception { + if (this.target instanceof CorrelationStrategy && !StringUtils.hasText(this.methodName)) { + this.strategy = (CorrelationStrategy) this.target; return; } - if (target != null) { - if (StringUtils.hasText(methodName)) { - delegate = new MethodInvokingCorrelationStrategy(target, methodName); + if (this.target != null) { + if (StringUtils.hasText(this.methodName)) { + this.strategy = new MethodInvokingCorrelationStrategy(this.target, this.methodName); } else { - Method method = MessagingAnnotationUtils.findAnnotatedMethod(target, + Method method = MessagingAnnotationUtils.findAnnotatedMethod(this.target, org.springframework.integration.annotation.CorrelationStrategy.class); if (method != null) { - delegate = new MethodInvokingCorrelationStrategy(target, method); + this.strategy = new MethodInvokingCorrelationStrategy(this.target, method); } } } } public CorrelationStrategy getObject() throws Exception { - return delegate; + return this.strategy; } public Class getObjectType() { diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java index f2b8288b57..47917e2273 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ReleaseStrategyFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.config; import java.lang.reflect.Method; @@ -21,6 +22,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; import org.springframework.integration.aggregator.MethodInvokingReleaseStrategy; import org.springframework.integration.aggregator.ReleaseStrategy; import org.springframework.integration.aggregator.SequenceSizeReleaseStrategy; @@ -28,55 +30,83 @@ import org.springframework.integration.util.MessagingAnnotationUtils; import org.springframework.util.StringUtils; /** - * Convenience factory for XML configuration of a {@link ReleaseStrategy}. Encapsulates the knowledge of the default - * strategy and search algorithms for POJO and annotated methods. + * Convenience factory for XML configuration of a {@link ReleaseStrategy}. + * Encapsulates the knowledge of the default strategy and search algorithms for POJO and annotated methods. * * @author Dave Syer * @author Gary Russell + * @author Artem Bilan * */ -public class ReleaseStrategyFactoryBean implements FactoryBean { +public class ReleaseStrategyFactoryBean implements FactoryBean, InitializingBean { private static final Log logger = LogFactory.getLog(ReleaseStrategyFactoryBean.class); - private ReleaseStrategy delegate = new SequenceSizeReleaseStrategy(); + private Object target; - /** - * Create a factory and set up the delegate which clients of the factory will see as its product. - * - * @param target the target object (null if default strategy is acceptable) - */ - public ReleaseStrategyFactoryBean(Object target) { - this(target, null); + private String methodName; + + private ReleaseStrategy strategy = new SequenceSizeReleaseStrategy(); + + public ReleaseStrategyFactoryBean() { } /** - * Create a factory and set up the delegate which clients of the factory will see as its product. - * + * Create a factory and set up the strategy which clients of the factory will see as its product. + * @param target the target object (null if default strategy is acceptable) + * @deprecated since {@literal 4.2.5} in favor of appropriate setters + * to avoid {@code BeanCurrentlyInCreationException} + * during {@code AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck()} + */ + @Deprecated + public ReleaseStrategyFactoryBean(Object target) { + this.target = target; + } + + /** + * Create a factory and set up the strategy which clients of the factory will see as its product. * @param target the target object (null if default strategy is acceptable) * @param methodName the method name to invoke in the target (null if it can be inferred) + * @deprecated since {@literal 4.2.5} in favor of appropriate setters + * to avoid {@code BeanCurrentlyInCreationException} + * during {@code AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck()} */ + @Deprecated public ReleaseStrategyFactoryBean(Object target, String methodName) { - if (target instanceof ReleaseStrategy && !StringUtils.hasText(methodName)) { - this.delegate = (ReleaseStrategy) target; + this.target = target; + this.methodName = methodName; + } + + public void setTarget(Object target) { + this.target = target; + } + + public void setMethodName(String methodName) { + this.methodName = methodName; + } + + @Override + public void afterPropertiesSet() throws Exception { + if (this.target instanceof ReleaseStrategy && !StringUtils.hasText(this.methodName)) { + this.strategy = (ReleaseStrategy) this.target; return; } - if (target != null) { - if (StringUtils.hasText(methodName)) { - this.delegate = new MethodInvokingReleaseStrategy(target, methodName); + if (this.target != null) { + if (StringUtils.hasText(this.methodName)) { + this.strategy = new MethodInvokingReleaseStrategy(this.target, this.methodName); } else { - Method method = MessagingAnnotationUtils.findAnnotatedMethod(target, + Method method = MessagingAnnotationUtils.findAnnotatedMethod(this.target, org.springframework.integration.annotation.ReleaseStrategy.class); if (method != null) { - this.delegate = new MethodInvokingReleaseStrategy(target, method); + this.strategy = new MethodInvokingReleaseStrategy(this.target, method); } else { if (logger.isWarnEnabled()) { logger.warn("No ReleaseStrategy annotated method found on " - + target.getClass().getSimpleName() + + this.target.getClass().getSimpleName() + "; falling back to SequenceSizeReleaseStrategy, target:" - + target + ", methodName:" + methodName); + + this.target + ", methodName:" + this.methodName); } } } @@ -90,7 +120,7 @@ public class ReleaseStrategyFactoryBean implements FactoryBean @Override public ReleaseStrategy getObject() throws Exception { - return this.delegate; + return this.strategy; } @Override diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java index f95bfc3c54..eff2f84863 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/xml/IntegrationNamespaceUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at @@ -266,15 +266,16 @@ public abstract class IntegrationNamespaceUtils { } /** - * Get a text value from a named attribute if it exists, otherwise check for a nested element of the same name. If - * both are specified it is an error, but if neither is specified, just returns null. + * Get a text value from a named attribute if it exists, otherwise check for a nested element of the same name. + * If both are specified it is an error, but if neither is specified, just returns null. * * @param element a DOM node * @param name the name of the property (attribute or child element) * @param parserContext the current context - * @return the text from the attribite or element or null + * @return the text from the attribute or element or null */ - public static String getTextFromAttributeOrNestedElement(Element element, String name, ParserContext parserContext) { + public static String getTextFromAttributeOrNestedElement(Element element, String name, + ParserContext parserContext) { String attr = element.getAttribute(name); Element childElement = DomUtils.getChildElementByTagName(element, name); if (StringUtils.hasText(attr) && childElement != null) { @@ -305,7 +306,8 @@ public abstract class IntegrationNamespaceUtils { parserContext.getReaderContext().error( "Ambiguous definition. Inner bean " + (innerComponentDefinition.getBeanDefinition().getBeanClassName()) + " declaration and \"ref\" " + ref + " are not allowed together on element " + - IntegrationNamespaceUtils.createElementDescription(element) + ".", parserContext.extractSource(element)); + IntegrationNamespaceUtils.createElementDescription(element) + ".", + parserContext.extractSource(element)); } return innerComponentDefinition; } @@ -616,13 +618,14 @@ public abstract class IntegrationNamespaceUtils { return adapter; } - private static BeanMetadataElement createAdapter(BeanMetadataElement ref, String method, String unqualifiedClassName) { + private static BeanMetadataElement createAdapter(BeanMetadataElement ref, String method, + String unqualifiedClassName) { BeanDefinitionBuilder builder = BeanDefinitionBuilder .genericBeanDefinition(IntegrationConfigUtils.BASE_PACKAGE + ".config." + unqualifiedClassName + "FactoryBean"); - builder.addConstructorArgValue(ref); + builder.addPropertyValue("target", ref); if (StringUtils.hasText(method)) { - builder.addConstructorArgValue(method); + builder.addPropertyValue("methodName", method); } return builder.getBeanDefinition(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java index 0fdf1901ec..343e755eba 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/ReleaseStrategyFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2014 the original author or authors. + * Copyright 2014-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,10 +15,12 @@ */ package org.springframework.integration.config; +import static org.hamcrest.Matchers.containsString; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.instanceOf; import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertThat; +import static org.junit.Assert.fail; import java.util.Collection; @@ -32,34 +34,49 @@ import org.springframework.integration.test.util.TestUtils; /** * @author Gary Russell + * @author Artem Bilan * @since 3.0.2 - * */ public class ReleaseStrategyFactoryBeanTests { - public void testRefWithMethod() throws Exception { + @Test + public void testRefWithNoMethod() throws Exception { Foo foo = new Foo(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo, "doRelease"); - ReleaseStrategy delegate = factory.getObject(); - assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); - assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Foo.class), is(foo)); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(foo); + factory.setMethodName("doRelease"); + try { + factory.afterPropertiesSet(); + fail("IllegalArgumentException expected"); + } + catch (Exception e) { + assertThat(e, instanceOf(IllegalArgumentException.class)); + assertThat(e.getMessage(), containsString("Target object of type " + + "[class org.springframework.integration.config.ReleaseStrategyFactoryBeanTests$Foo] " + + "has no eligible methods for handling Messages.")); + } } @Test public void testRefWithMethodWithDifferentAnnotatedMethod() throws Exception { Bar bar = new Bar(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar, "doRelease2"); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(bar); + factory.setMethodName("doRelease2"); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar)); - assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class), + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression"), equalTo("#target.doRelease2(messages)")); } @Test public void testRefWithNoMethodWithAnnotation() throws Exception { Bar bar = new Bar(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(bar); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(bar); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Bar.class), is(bar)); @@ -67,7 +84,8 @@ public class ReleaseStrategyFactoryBeanTests { @Test public void testNoRefNoMethod() throws Exception { - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(null); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class)); } @@ -75,7 +93,9 @@ public class ReleaseStrategyFactoryBeanTests { @Test public void testRefWithNoMethodNoAnnotation() throws Exception { Foo foo = new Foo(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(foo); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(foo); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); assertThat(delegate, instanceOf(SequenceSizeReleaseStrategy.class)); } @@ -83,19 +103,24 @@ public class ReleaseStrategyFactoryBeanTests { @Test public void testRefThatImplements() throws Exception { Baz baz = new Baz(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(baz); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); - assertThat((Baz) delegate, is(baz)); + assertThat(delegate, is(baz)); } @Test public void testRefThatImplementsWithDifferentMethod() throws Exception { Baz baz = new Baz(); - ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(baz, "doRelease2"); + ReleaseStrategyFactoryBean factory = new ReleaseStrategyFactoryBean(); + factory.setTarget(baz); + factory.setMethodName("doRelease2"); + factory.afterPropertiesSet(); ReleaseStrategy delegate = factory.getObject(); assertThat(delegate, instanceOf(MethodInvokingReleaseStrategy.class)); assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.targetObject", Baz.class), is(baz)); - assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression", String.class), + assertThat(TestUtils.getPropertyValue(delegate, "adapter.delegate.handlerMethod.expression.expression"), equalTo("#target.doRelease2(messages)")); } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/AbstractJpaOutboundGatewayParser.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/AbstractJpaOutboundGatewayParser.java index a6d662858b..d1d38437f1 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/AbstractJpaOutboundGatewayParser.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/AbstractJpaOutboundGatewayParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,8 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.jpa.config.xml; +import org.w3c.dom.Element; + import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.support.ManagedList; @@ -24,7 +27,6 @@ import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.jpa.outbound.JpaOutboundGatewayFactoryBean; import org.springframework.util.StringUtils; import org.springframework.util.xml.DomUtils; -import org.w3c.dom.Element; /** * The Abstract Parser for the JPA Outbound Gateways. @@ -42,14 +44,13 @@ public abstract class AbstractJpaOutboundGatewayParser extends AbstractConsumerE @Override protected BeanDefinitionBuilder parseHandler(Element gatewayElement, ParserContext parserContext) { - - final BeanDefinitionBuilder jpaOutboundGatewayBuilder = BeanDefinitionBuilder - .genericBeanDefinition(JpaOutboundGatewayFactoryBean.class); + final BeanDefinitionBuilder jpaOutboundGatewayBuilder = + BeanDefinitionBuilder.genericBeanDefinition(JpaOutboundGatewayFactoryBean.class); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaOutboundGatewayBuilder, gatewayElement, "reply-timeout"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaOutboundGatewayBuilder, gatewayElement, "requires-reply"); - final String replyChannel = gatewayElement.getAttribute("reply-channel"); + String replyChannel = gatewayElement.getAttribute("reply-channel"); if (StringUtils.hasText(replyChannel)) { jpaOutboundGatewayBuilder.addPropertyReference("outputChannel", replyChannel); @@ -58,7 +59,8 @@ public abstract class AbstractJpaOutboundGatewayParser extends AbstractConsumerE final Element transactionalElement = DomUtils.getChildElementByTagName(gatewayElement, "transactional"); if (transactionalElement != null) { - BeanDefinition txAdviceDefinition = IntegrationNamespaceUtils.configureTransactionAttributes(transactionalElement); + BeanDefinition txAdviceDefinition = + IntegrationNamespaceUtils.configureTransactionAttributes(transactionalElement); ManagedList adviceChain = new ManagedList(); adviceChain.add(txAdviceDefinition); jpaOutboundGatewayBuilder.addPropertyValue("txAdviceChain", adviceChain); diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/JpaOutboundChannelAdapterParser.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/JpaOutboundChannelAdapterParser.java index 19fcd101d8..5d47804ae5 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/JpaOutboundChannelAdapterParser.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/JpaOutboundChannelAdapterParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.jpa.config.xml; import org.w3c.dom.Element; @@ -33,6 +34,7 @@ import org.springframework.util.xml.DomUtils; * * @author Amol Nayak * @author Gunnar Hillert + * @author Artem Bilan * * @since 2.2 * @@ -52,7 +54,8 @@ public class JpaOutboundChannelAdapterParser extends AbstractOutboundChannelAdap @Override protected AbstractBeanDefinition parseConsumer(Element element, ParserContext parserContext) { - final BeanDefinitionBuilder jpaOutboundChannelAdapterBuilder = BeanDefinitionBuilder.genericBeanDefinition(JpaOutboundGatewayFactoryBean.class); + final BeanDefinitionBuilder jpaOutboundChannelAdapterBuilder = + BeanDefinitionBuilder.genericBeanDefinition(JpaOutboundGatewayFactoryBean.class); final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getJpaExecutorBuilder(element, parserContext); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "persist-mode"); @@ -60,21 +63,25 @@ public class JpaOutboundChannelAdapterParser extends AbstractOutboundChannelAdap IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "flush-size"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "clear-on-flush"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "parameter-source-factory"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, "use-payload-as-parameter-source"); + IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, element, + "use-payload-as-parameter-source"); final BeanDefinition jpaExecutorBuilderBeanDefinition = jpaExecutorBuilder.getBeanDefinition(); - final String channelAdapterId = this.resolveId(element, jpaOutboundChannelAdapterBuilder.getRawBeanDefinition(), parserContext); + final String channelAdapterId = resolveId(element, jpaOutboundChannelAdapterBuilder.getRawBeanDefinition(), + parserContext); final String jpaExecutorBeanName = channelAdapterId + ".jpaExecutor"; - parserContext.registerBeanComponent(new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); + parserContext.registerBeanComponent( + new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); - jpaOutboundChannelAdapterBuilder.addConstructorArgReference(jpaExecutorBeanName); - jpaOutboundChannelAdapterBuilder.addPropertyValue("producesReply", Boolean.FALSE); + jpaOutboundChannelAdapterBuilder.addPropertyReference("jpaExecutor", jpaExecutorBeanName) + .addPropertyValue("producesReply", Boolean.FALSE); final Element transactionalElement = DomUtils.getChildElementByTagName(element, "transactional"); if(transactionalElement != null) { - BeanDefinition txAdviceDefinition = IntegrationNamespaceUtils.configureTransactionAttributes(transactionalElement); + BeanDefinition txAdviceDefinition = + IntegrationNamespaceUtils.configureTransactionAttributes(transactionalElement); ManagedList adviceChain = new ManagedList(); adviceChain.add(txAdviceDefinition); jpaOutboundChannelAdapterBuilder.addPropertyValue("txAdviceChain", adviceChain); diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/RetrievingJpaOutboundGatewayParser.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/RetrievingJpaOutboundGatewayParser.java index 96ae26f653..45ab0b39cc 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/RetrievingJpaOutboundGatewayParser.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/RetrievingJpaOutboundGatewayParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,16 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + package org.springframework.integration.jpa.config.xml; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.support.AbstractBeanDefinition; import org.springframework.beans.factory.support.BeanDefinitionBuilder; import org.springframework.beans.factory.xml.ParserContext; -import org.springframework.integration.config.ExpressionFactoryBean; import org.springframework.integration.config.xml.IntegrationNamespaceUtils; import org.springframework.integration.jpa.support.OutboundGatewayType; import org.springframework.util.CollectionUtils; @@ -34,6 +33,7 @@ import org.springframework.util.xml.DomUtils; * * @author Amol Nayak * @author Gunnar Hillert + * @author Artem Bilan * @since 2.2 */ public class RetrievingJpaOutboundGatewayParser extends AbstractJpaOutboundGatewayParser { @@ -43,7 +43,8 @@ public class RetrievingJpaOutboundGatewayParser extends AbstractJpaOutboundGatew final BeanDefinitionBuilder jpaOutboundGatewayBuilder = super.parseHandler(gatewayElement, parserContext); - final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getOutboundGatewayJpaExecutorBuilder(gatewayElement, parserContext); + final BeanDefinitionBuilder jpaExecutorBuilder = + JpaParserUtils.getOutboundGatewayJpaExecutorBuilder(gatewayElement, parserContext); BeanDefinition firstResultExpression = IntegrationNamespaceUtils .createExpressionDefinitionFromValueOrExpression("first-result", "first-result-expression", @@ -59,8 +60,7 @@ public class RetrievingJpaOutboundGatewayParser extends AbstractJpaOutboundGatew jpaExecutorBuilder.addPropertyValue("maxResultsExpression", maxResultsExpression); } - String idExpression = gatewayElement.getAttribute("id-expression"); - if (StringUtils.hasText(idExpression)) { + if (StringUtils.hasText(gatewayElement.getAttribute("id-expression"))) { String[] otherAttributes = {"jpa-query", "native-query", "named-query", "first-result", "first-result-expression", "max-results", "max-results-expression", "delete-in-batch", "expect-single-result", "parameter-source-factory", "use-payload-as-parameter-source"}; @@ -84,27 +84,26 @@ public class RetrievingJpaOutboundGatewayParser extends AbstractJpaOutboundGatew + "not allowed with an 'id-expression' attribute.", gatewayElement); } - AbstractBeanDefinition idExpressionDef = BeanDefinitionBuilder.genericBeanDefinition(ExpressionFactoryBean.class) - .addConstructorArgValue(idExpression) - .getBeanDefinition(); + BeanDefinition idExpressionDef = + IntegrationNamespaceUtils.createExpressionDefIfAttributeDefined("id-expression", gatewayElement); jpaExecutorBuilder.addPropertyValue("idExpression", idExpressionDef); } IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "delete-after-poll"); - IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "flush-after-delete", "flush"); + IntegrationNamespaceUtils.setValueIfAttributeDefined( + jpaExecutorBuilder, gatewayElement, "flush-after-delete", "flush"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "delete-in-batch"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "expect-single-result"); final BeanDefinition jpaExecutorBuilderBeanDefinition = jpaExecutorBuilder.getBeanDefinition(); - final String gatewayId = this.resolveId(gatewayElement, jpaOutboundGatewayBuilder.getRawBeanDefinition(), parserContext); + final String gatewayId = resolveId(gatewayElement, jpaOutboundGatewayBuilder.getRawBeanDefinition(), parserContext); final String jpaExecutorBeanName = gatewayId + ".jpaExecutor"; - parserContext.registerBeanComponent(new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); + parserContext.registerBeanComponent( + new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); - jpaOutboundGatewayBuilder.addConstructorArgReference(jpaExecutorBeanName); - jpaOutboundGatewayBuilder.addPropertyValue("gatewayType", OutboundGatewayType.RETRIEVING); - - return jpaOutboundGatewayBuilder; + return jpaOutboundGatewayBuilder.addPropertyReference("jpaExecutor", jpaExecutorBeanName) + .addPropertyValue("gatewayType", OutboundGatewayType.RETRIEVING); } } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/UpdatingJpaOutboundGatewayParser.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/UpdatingJpaOutboundGatewayParser.java index 40bbd80ef7..b25ef69ab4 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/UpdatingJpaOutboundGatewayParser.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/config/xml/UpdatingJpaOutboundGatewayParser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,6 +29,7 @@ import org.springframework.integration.jpa.support.OutboundGatewayType; * * @author Amol Nayak * @author Gunnar Hillert + * @author Artem Bilan * * @since 2.2 * @@ -37,10 +38,10 @@ public class UpdatingJpaOutboundGatewayParser extends AbstractJpaOutboundGateway @Override protected BeanDefinitionBuilder parseHandler(Element gatewayElement, ParserContext parserContext) { + BeanDefinitionBuilder jpaOutboundGatewayBuilder = super.parseHandler(gatewayElement, parserContext); - final BeanDefinitionBuilder jpaOutboundGatewayBuilder = super.parseHandler(gatewayElement, parserContext); - - final BeanDefinitionBuilder jpaExecutorBuilder = JpaParserUtils.getOutboundGatewayJpaExecutorBuilder(gatewayElement, parserContext); + BeanDefinitionBuilder jpaExecutorBuilder = + JpaParserUtils.getOutboundGatewayJpaExecutorBuilder(gatewayElement, parserContext); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "persist-mode"); IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "flush"); @@ -48,15 +49,15 @@ public class UpdatingJpaOutboundGatewayParser extends AbstractJpaOutboundGateway IntegrationNamespaceUtils.setValueIfAttributeDefined(jpaExecutorBuilder, gatewayElement, "clear-on-flush"); final BeanDefinition jpaExecutorBuilderBeanDefinition = jpaExecutorBuilder.getBeanDefinition(); - final String gatewayId = this.resolveId(gatewayElement, jpaOutboundGatewayBuilder.getRawBeanDefinition(), parserContext); + final String gatewayId = resolveId(gatewayElement, jpaOutboundGatewayBuilder.getRawBeanDefinition(), + parserContext); final String jpaExecutorBeanName = gatewayId + ".jpaExecutor"; - parserContext.registerBeanComponent(new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); - - jpaOutboundGatewayBuilder.addConstructorArgReference(jpaExecutorBeanName); - jpaOutboundGatewayBuilder.addPropertyValue("gatewayType", OutboundGatewayType.UPDATING); - return jpaOutboundGatewayBuilder; + parserContext.registerBeanComponent( + new BeanComponentDefinition(jpaExecutorBuilderBeanDefinition, jpaExecutorBeanName)); + return jpaOutboundGatewayBuilder.addPropertyReference("jpaExecutor", jpaExecutorBeanName) + .addPropertyValue("gatewayType", OutboundGatewayType.UPDATING); } } diff --git a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayFactoryBean.java b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayFactoryBean.java index 30704e082d..17690f4746 100644 --- a/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayFactoryBean.java +++ b/spring-integration-jpa/src/main/java/org/springframework/integration/jpa/outbound/JpaOutboundGatewayFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,7 +28,6 @@ import org.springframework.integration.jpa.support.OutboundGatewayType; import org.springframework.messaging.MessageChannel; import org.springframework.messaging.MessageHandler; import org.springframework.transaction.interceptor.TransactionInterceptor; -import org.springframework.util.Assert; import org.springframework.util.ClassUtils; import org.springframework.util.CollectionUtils; @@ -47,21 +46,21 @@ import org.springframework.util.CollectionUtils; */ public class JpaOutboundGatewayFactoryBean extends AbstractFactoryBean { - private final JpaExecutor jpaExecutor; + private JpaExecutor jpaExecutor; private OutboundGatewayType gatewayType = OutboundGatewayType.UPDATING; /** * <transactional /> element applies to entire flow from this point */ - private volatile List txAdviceChain; + private List txAdviceChain; /** * <request-handler-advice-chain /> only applies to the handleRequestMessage. */ - private volatile List adviceChain; + private List adviceChain; - private volatile ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); + private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader(); private boolean producesReply = true; @@ -71,18 +70,26 @@ public class JpaOutboundGatewayFactoryBean extends AbstractFactoryBean getObjectType() { return MessageHandler.class; @@ -141,7 +153,6 @@ public class JpaOutboundGatewayFactoryBean extends AbstractFactoryBean implements ApplicationContextAware { - private final ServletWebSocketHandlerRegistry registry; + private ServletWebSocketHandlerRegistry registry; private ApplicationContext applicationContext; - private WebSocketHandlerMappingFactoryBean(ThreadPoolTaskScheduler sockJsTaskScheduler) { + public void setSockJsTaskScheduler(ThreadPoolTaskScheduler sockJsTaskScheduler) { this.registry = new ServletWebSocketHandlerRegistry(sockJsTaskScheduler); } @@ -140,6 +140,7 @@ public class WebSocketIntegrationConfigurationInitializer implements Integration public Class getObjectType() { return HandlerMapping.class; } + } } diff --git a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBean.java b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBean.java index feb5706c4e..73ad4ea024 100644 --- a/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBean.java +++ b/spring-integration-xmpp/src/main/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -26,7 +26,6 @@ import org.jxmpp.util.XmppStringUtils; import org.springframework.beans.factory.BeanInitializationException; import org.springframework.beans.factory.config.AbstractFactoryBean; import org.springframework.context.SmartLifecycle; -import org.springframework.util.Assert; import org.springframework.util.StringUtils; /** @@ -44,10 +43,10 @@ import org.springframework.util.StringUtils; */ public class XmppConnectionFactoryBean extends AbstractFactoryBean implements SmartLifecycle { - private final XMPPTCPConnectionConfiguration connectionConfiguration; - private final Object lifecycleMonitor = new Object(); + private XMPPTCPConnectionConfiguration connectionConfiguration; + private volatile String resource; // server will generate resource if not provided private volatile String user; @@ -72,11 +71,24 @@ public class XmppConnectionFactoryBean extends AbstractFactoryBean - + - + diff --git a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBeanTests.java b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBeanTests.java index 6fff0a3499..40d558a74d 100644 --- a/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBeanTests.java +++ b/spring-integration-xmpp/src/test/java/org/springframework/integration/xmpp/config/XmppConnectionFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2015 the original author or authors. + * Copyright 2002-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,13 +28,14 @@ import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author Oleg Zhurakousky * @author Gunnar Hillert + * @author Artem Bilan */ public class XmppConnectionFactoryBeanTests { @Test public void testXmppConnectionFactoryBean() throws Exception { - XmppConnectionFactoryBean xmppConnectionFactoryBean = - new XmppConnectionFactoryBean(mock(XMPPTCPConnectionConfiguration.class)); + XmppConnectionFactoryBean xmppConnectionFactoryBean = new XmppConnectionFactoryBean(); + xmppConnectionFactoryBean.setConnectionConfiguration(mock(XMPPTCPConnectionConfiguration.class)); XMPPConnection connection = xmppConnectionFactoryBean.createInstance(); assertNotNull(connection); } diff --git a/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBean.java b/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBean.java index 2d50721f1e..a7277ab0e4 100644 --- a/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBean.java +++ b/spring-integration-zookeeper/src/main/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -33,17 +33,18 @@ import org.springframework.integration.zookeeper.leader.LeaderInitiator; * Creates a {@link LeaderInitiator}. * * @author Gary Russell + * @author Artem Bilan * @since 4.2 * */ public class LeaderInitiatorFactoryBean implements FactoryBean, SmartLifecycle, InitializingBean, ApplicationEventPublisherAware { - private final CuratorFramework client; + private CuratorFramework client; - private final Candidate candidate; + private Candidate candidate; - private final String path; + private String path; private LeaderInitiator leaderInitiator; @@ -53,16 +54,38 @@ public class LeaderInitiatorFactoryBean private ApplicationEventPublisher applicationEventPublisher; + public LeaderInitiatorFactoryBean() { + } + /** * Construct the instance. * @param client the {@link CuratorFramework}. * @param path the path in zookeeper. * @param role the role of the leader. + * @deprecated since {@literal 4.2.5} in favor of appropriate setters + * to avoid {@code BeanCurrentlyInCreationException} + * during {@code AbstractAutowireCapableBeanFactory.getSingletonFactoryBeanForTypeCheck()} */ + @Deprecated public LeaderInitiatorFactoryBean(CuratorFramework client, String path, String role) { this.client = client; - this.candidate = new DefaultCandidate(UUID.randomUUID().toString(), role); this.path = path; + this.candidate = new DefaultCandidate(UUID.randomUUID().toString(), role); + } + + public LeaderInitiatorFactoryBean setClient(CuratorFramework client) { + this.client = client; + return this; + } + + public LeaderInitiatorFactoryBean setPath(String path) { + this.path = path; + return this; + } + + public LeaderInitiatorFactoryBean setRole(String role) { + this.candidate = new DefaultCandidate(UUID.randomUUID().toString(), role); + return this; } @Override diff --git a/spring-integration-zookeeper/src/test/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBeanTests.java b/spring-integration-zookeeper/src/test/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBeanTests.java index a58a11e35a..1ba0ba19fc 100644 --- a/spring-integration-zookeeper/src/test/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBeanTests.java +++ b/spring-integration-zookeeper/src/test/java/org/springframework/integration/zookeeper/config/LeaderInitiatorFactoryBeanTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2015 the original author or authors. + * Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -44,6 +44,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; /** * @author Gary Russell + * @author Artem Bilan * @since 4.2 * */ @@ -85,7 +86,10 @@ public class LeaderInitiatorFactoryBeanTests extends ZookeeperTestSupport { @Bean public LeaderInitiatorFactoryBean leaderInitiator(CuratorFramework client) { - return new LeaderInitiatorFactoryBean(client, "/siTest/", "foo"); + return new LeaderInitiatorFactoryBean() + .setClient(client) + .setPath("/siTest/") + .setRole("foo"); } @Bean