diff --git a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java
index 20c0c8e7a6..0f53a91058 100644
--- a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.java
+++ b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/RmiOutboundGateway.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.
@@ -37,14 +37,33 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
private final RequestReplyExchanger proxy;
+ private final RmiProxyFactoryBeanConfigurer configurer;
+ /**
+ * Construct an instance with a `RequestReplyExchanger` built from the
+ * default {@link RmiProxyFactoryBean}.
+ * @param url the url.
+ */
public RmiOutboundGateway(String url) {
- this.proxy = this.createProxy(url);
+ this(url, null);
+ }
+
+ /**
+ * Construct an instance with a `RequestReplyExchanger` built from the
+ * default {@link RmiProxyFactoryBean} which can be modified by the
+ * configurer.
+ * @param url the url.
+ * @param configurer the {@link RmiProxyFactoryBeanConfigurer}.
+ * @since 4.3.2
+ */
+ public RmiOutboundGateway(String url, RmiProxyFactoryBeanConfigurer configurer) {
+ this.configurer = configurer;
+ this.proxy = createProxy(url);
}
public void setReplyChannel(MessageChannel replyChannel) {
- this.setOutputChannel(replyChannel);
+ setOutputChannel(replyChannel);
}
@Override
@@ -64,7 +83,10 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
try {
Message> reply = this.proxy.exchange(requestMessage);
if (reply != null) {
- reply = this.getMessageBuilderFactory().fromMessage(reply).copyHeadersIfAbsent(message.getHeaders()).build();
+ reply = getMessageBuilderFactory()
+ .fromMessage(reply)
+ .copyHeadersIfAbsent(message.getHeaders())
+ .build();
}
return reply;
}
@@ -72,7 +94,8 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
throw new MessageHandlingException(message, e);
}
catch (RemoteAccessException e) {
- throw new MessageHandlingException(message, "Remote failure in RmiOutboundGateway: " + this.getComponentName(), e);
+ throw new MessageHandlingException(message, "Remote failure in RmiOutboundGateway: " +
+ this.getComponentName(), e);
}
}
@@ -82,8 +105,26 @@ public class RmiOutboundGateway extends AbstractReplyProducingMessageHandler {
proxyFactory.setServiceUrl(url);
proxyFactory.setLookupStubOnStartup(false);
proxyFactory.setRefreshStubOnConnectFailure(true);
+ if (this.configurer != null) {
+ this.configurer.configure(proxyFactory);
+ }
proxyFactory.afterPropertiesSet();
return (RequestReplyExchanger) proxyFactory.getObject();
}
+ /**
+ * Allows configuration of the proxy factory bean before the RMI proxy is created.
+ * @since 4.3.2
+ */
+ public interface RmiProxyFactoryBeanConfigurer {
+
+ /**
+ * Perform additional configuration of the factory bean before the
+ * {@code RequestReplyExchanger} is created.
+ * @param factoryBean the factory bean.
+ */
+ void configure(RmiProxyFactoryBean factoryBean);
+
+ }
+
}
diff --git a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java
index 0cd2b1b481..ea9cae789d 100644
--- a/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java
+++ b/spring-integration-rmi/src/main/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParser.java
@@ -20,9 +20,11 @@ import java.rmi.registry.Registry;
import org.w3c.dom.Element;
+import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.integration.config.xml.AbstractOutboundGatewayParser;
import org.springframework.integration.rmi.RmiInboundGateway;
+import org.springframework.integration.rmi.RmiOutboundGateway;
import org.springframework.util.StringUtils;
/**
@@ -34,7 +36,7 @@ public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser {
@Override
protected String getGatewayClassName(Element element) {
- return "org.springframework.integration.rmi.RmiOutboundGateway";
+ return RmiOutboundGateway.class.getName();
}
@Override
@@ -50,4 +52,11 @@ public class RmiOutboundGatewayParser extends AbstractOutboundGatewayParser {
return "rmi://" + host + ":" + port + "/" + RmiInboundGateway.SERVICE_NAME_PREFIX + remoteChannel;
}
+ @Override
+ protected void postProcessGateway(BeanDefinitionBuilder builder, Element element, ParserContext parserContext) {
+ if (StringUtils.hasText(element.getAttribute("configurer"))) {
+ builder.addConstructorArgReference(element.getAttribute("configurer"));
+ }
+ }
+
}
diff --git a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd
index 8c91357c89..7d821fd740 100644
--- a/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd
+++ b/spring-integration-rmi/src/main/resources/org/springframework/integration/rmi/config/spring-integration-rmi-5.0.xsd
@@ -114,6 +114,20 @@
+
+
+
+ Specify a 'RmiProxyFactoryBeanConfigurer' to further configure the RmiProxyFactoryBean
+ before it creates the proxy - use this, for example,
+ to customize the RemoteInvocationFactory.
+
+
+
+
+
+
+
+
diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml
index 27d88d3384..102914efee 100644
--- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml
+++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests-context.xml
@@ -16,6 +16,7 @@
order="23"
request-channel="localChannel"
remote-channel="testChannel"
+ configurer="configurer"
host="localhost"/>
@@ -30,6 +31,11 @@
+
+
+
+
diff --git a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java
index bc51255a73..0c6db3b17b 100644
--- a/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java
+++ b/spring-integration-rmi/src/test/java/org/springframework/integration/rmi/config/RmiOutboundGatewayParserTests.java
@@ -19,8 +19,11 @@ package org.springframework.integration.rmi.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
+import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
import org.junit.BeforeClass;
import org.junit.Test;
@@ -39,6 +42,7 @@ import org.springframework.messaging.Message;
import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.PollableChannel;
import org.springframework.messaging.support.GenericMessage;
+import org.springframework.remoting.rmi.RmiProxyFactoryBean;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@@ -70,6 +74,9 @@ public class RmiOutboundGatewayParserTests {
@Autowired
private PollableChannel replyChannel;
+ @Autowired
+ private RmiOutboundGateway.RmiProxyFactoryBeanConfigurer configurer;
+
@Autowired
@Qualifier("gateway.handler")
RmiOutboundGateway gateway;
@@ -89,9 +96,11 @@ public class RmiOutboundGatewayParserTests {
}
@Test
- public void testOrder() {
+ public void testProperties() {
assertEquals(23, TestUtils.getPropertyValue(gateway, "order"));
assertTrue(TestUtils.getPropertyValue(gateway, "requiresReply", Boolean.class));
+ assertSame(this.configurer, TestUtils.getPropertyValue(this.gateway, "configurer"));
+ verify(this.configurer).configure(any(RmiProxyFactoryBean.class));
}
@Test
diff --git a/src/reference/asciidoc/rmi.adoc b/src/reference/asciidoc/rmi.adoc
index e595269607..42163e8822 100644
--- a/src/reference/asciidoc/rmi.adoc
+++ b/src/reference/asciidoc/rmi.adoc
@@ -75,3 +75,44 @@ The following code snippet shows the different configuration for an outbound rmi
remote-channel="testChannel"
host="localhost"/>
----
+
+=== Configuring with Java Configuration
+
+[source, java]
+----
+@Bean
+public RmiInboundGateway inbound() {
+ RmiInboundGateway gateway = new RmiInboundGateway();
+ gateway.setRequestChannel(requestChannel());
+ gateway.setRegistryHost("host");
+ gateway.setRegistryPort(port);
+ return gateway;
+}
+
+@Bean
+@ServiceActivator(inputChannel="inChannel")
+public RmiOutboundGateway outbound() {
+ RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://host:port/"
+ + RmiInboundGateway.SERVICE_NAME_PREFIX + "remoteChannelName");
+ return gateway;
+}
+----
+
+Starting with _version 4.3_, the outbound gateway has a second constructor that takes a RmiProxyFactoryBeanConfigurer instance along with the service url argument.
+This allows further configuration before the proxy is created; for example, to inject a Spring Security `ContextPropagatingRemoteInvocationFactory`:
+
+[source, java]
+----
+@Bean
+@ServiceActivator(inputChannel="inChannel")
+public RmiOutboundGateway outbound() {
+ RmiOutboundGateway gateway = new RmiOutboundGateway("rmi://host:port/"
+ + RmiInboundGateway.SERVICE_NAME_PREFIX + "remoteChannelName",
+ pfb -> {
+ pfb.setRemoteInvocationFactory(new ContextPropagatingRemoteInvocationFactory());
+ });
+ return gateway;
+}
+----
+
+Starting with _version 5.0_, this can be set using the XML namespace, using the `configurer` attribute.