diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java b/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
index a7fdbff18a..fe4a3400f0 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/config/ConsumerEndpointFactoryBean.java
@@ -74,7 +74,7 @@ public class ConsumerEndpointFactoryBean
private volatile PollerMetadata pollerMetadata;
- private volatile boolean autoStartup = true;
+ private volatile Boolean autoStartup;
private volatile int phase = 0;
@@ -138,7 +138,7 @@ public class ConsumerEndpointFactoryBean
this.beanClassLoader = classLoader;
}
- public void setAutoStartup(boolean autoStartup) {
+ public void setAutoStartup(Boolean autoStartup) {
this.autoStartup = autoStartup;
}
@@ -267,7 +267,9 @@ public class ConsumerEndpointFactoryBean
Assert.isNull(this.pollerMetadata, "A poller should not be specified for endpoint '" + this.beanName
+ "', since '" + channel + "' is a SubscribableChannel (not pollable).");
this.endpoint = new EventDrivenConsumer((SubscribableChannel) channel, this.handler);
- if (this.logger.isWarnEnabled() && !this.autoStartup && channel instanceof FixedSubscriberChannel) {
+ if (this.logger.isWarnEnabled()
+ && Boolean.FALSE.equals(this.autoStartup)
+ && channel instanceof FixedSubscriberChannel) {
this.logger.warn("'autoStartup=\"false\"' has no effect when using a FixedSubscriberChannel");
}
}
@@ -297,7 +299,9 @@ public class ConsumerEndpointFactoryBean
}
this.endpoint.setBeanName(this.beanName);
this.endpoint.setBeanFactory(this.beanFactory);
- this.endpoint.setAutoStartup(this.autoStartup);
+ if (this.autoStartup != null) {
+ this.endpoint.setAutoStartup(this.autoStartup);
+ }
int phase = this.phase;
if (!this.isPhaseSet && this.endpoint instanceof PollingConsumer) {
phase = Integer.MAX_VALUE / 2;
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationProperties.java b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationProperties.java
index db06916cff..662fb3de0f 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationProperties.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationProperties.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2014-2016 the original author or authors.
+ * Copyright 2014-2017 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.core.io.support.ResourcePatternResolver;
* their default values from resources 'META-INF/spring.integration.default.properties'.
*
* @author Artem Bilan
+ *
* @since 3.0
*/
public final class IntegrationProperties {
@@ -71,6 +72,11 @@ public final class IntegrationProperties {
*/
public static final String READ_ONLY_HEADERS = INTEGRATION_PROPERTIES_PREFIX + "readOnly.headers";
+ /**
+ * Specifies the value of {@link org.springframework.integration.endpoint.AbstractEndpoint#autoStartup}.
+ */
+ public static final String ENDPOINTS_NO_AUTO_STARTUP = INTEGRATION_PROPERTIES_PREFIX + "endpoints.noAutoStartup";
+
private static Properties defaults;
diff --git a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java
index 7c3e0fdbad..a455495b55 100644
--- a/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java
+++ b/spring-integration-core/src/main/java/org/springframework/integration/endpoint/AbstractEndpoint.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2014 the original author or authors.
+ * Copyright 2002-2017 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.
@@ -21,7 +21,9 @@ import java.util.concurrent.locks.ReentrantLock;
import org.springframework.context.SmartLifecycle;
import org.springframework.integration.context.IntegrationObjectSupport;
+import org.springframework.integration.context.IntegrationProperties;
import org.springframework.scheduling.TaskScheduler;
+import org.springframework.util.PatternMatchUtils;
/**
* The base class for Message Endpoint implementations.
@@ -36,9 +38,12 @@ import org.springframework.scheduling.TaskScheduler;
* @author Mark Fisher
* @author Kris Jacyna
* @author Gary Russell
+ * @author Artem Bilan
*/
public abstract class AbstractEndpoint extends IntegrationObjectSupport implements SmartLifecycle {
+ private boolean autoStartupSetExplicitly;
+
private volatile boolean autoStartup = true;
private volatile int phase = 0;
@@ -52,6 +57,7 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport implemen
public void setAutoStartup(boolean autoStartup) {
this.autoStartup = autoStartup;
+ this.autoStartupSetExplicitly = true;
}
public void setPhase(int phase) {
@@ -63,6 +69,23 @@ public abstract class AbstractEndpoint extends IntegrationObjectSupport implemen
super.setTaskScheduler(taskScheduler);
}
+ @Override
+ protected void onInit() throws Exception {
+ super.onInit();
+
+ if (!this.autoStartupSetExplicitly) {
+ String[] endpointNamePatterns =
+ getIntegrationProperty(IntegrationProperties.ENDPOINTS_NO_AUTO_STARTUP, String[].class);
+
+ for (String pattern : endpointNamePatterns) {
+ if (PatternMatchUtils.simpleMatch(pattern, getComponentName())) {
+ this.autoStartup = false;
+ break;
+ }
+ }
+ }
+ }
+
// SmartLifecycle implementation
@Override
diff --git a/spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties b/spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties
index 650beed270..afdae85c7f 100644
--- a/spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties
+++ b/spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties
@@ -4,4 +4,5 @@ spring.integration.channels.maxBroadcastSubscribers=0x7fffffff
spring.integration.taskScheduler.poolSize=10
spring.integration.messagingTemplate.throwExceptionOnLateReply=false
# Defaults to MessageHeaders.ID and MessageHeaders.TIMESTAMP
-spring.integration.readOnly.headers=
\ No newline at end of file
+spring.integration.readOnly.headers=
+spring.integration.endpoints.noAutoStartup=
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests-context.xml b/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests-context.xml
index 4bbd23523b..cec135faa7 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests-context.xml
+++ b/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests-context.xml
@@ -11,4 +11,7 @@
+
+
diff --git a/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests.java b/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests.java
index 61965697b7..718e5c88a5 100644
--- a/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests.java
+++ b/spring-integration-core/src/test/java/org/springframework/integration/context/IntegrationContextTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2014 the original author or authors.
+ * Copyright 2013-2017 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.
@@ -17,6 +17,8 @@
package org.springframework.integration.context;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
import java.util.Properties;
@@ -25,6 +27,7 @@ import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.test.util.TestUtils;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.test.context.ContextConfiguration;
@@ -32,6 +35,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* @author Artem Bilan
+ *
* @since 3.0
*/
@ContextConfiguration
@@ -44,7 +48,11 @@ public class IntegrationContextTests {
@Autowired
@Qualifier("fooService")
- private IntegrationObjectSupport serviceActivator;
+ private AbstractEndpoint serviceActivator;
+
+ @Autowired
+ @Qualifier("fooServiceExplicit")
+ private AbstractEndpoint serviceActivatorExplicit;
@Autowired
private ThreadPoolTaskScheduler taskScheduler;
@@ -55,6 +63,10 @@ public class IntegrationContextTests {
assertEquals("20", this.integrationProperties.get(IntegrationProperties.TASK_SCHEDULER_POOL_SIZE));
assertEquals(this.integrationProperties, this.serviceActivator.getIntegrationProperties());
assertEquals(20, TestUtils.getPropertyValue(this.taskScheduler, "poolSize"));
+ assertFalse(this.serviceActivator.isAutoStartup());
+ assertFalse(this.serviceActivator.isRunning());
+ assertTrue(this.serviceActivatorExplicit.isAutoStartup());
+ assertTrue(this.serviceActivatorExplicit.isRunning());
}
}
diff --git a/spring-integration-core/src/test/resources/META-INF/spring.integration.properties b/spring-integration-core/src/test/resources/META-INF/spring.integration.properties
index 5c2d44fc6c..75c9245449 100644
--- a/spring-integration-core/src/test/resources/META-INF/spring.integration.properties
+++ b/spring-integration-core/src/test/resources/META-INF/spring.integration.properties
@@ -3,3 +3,4 @@
#spring.integration.channels.maxBroadcastSubscribers=1
spring.integration.taskScheduler.poolSize=20
spring.integration.messagingTemplate.throwExceptionOnLateReply=true
+spring.integration.endpoints.noAutoStartup=fooService*
diff --git a/src/reference/asciidoc/configuration.adoc b/src/reference/asciidoc/configuration.adoc
index 0311343a43..667da04596 100644
--- a/src/reference/asciidoc/configuration.adoc
+++ b/src/reference/asciidoc/configuration.adoc
@@ -222,6 +222,7 @@ spring.integration.channels.maxBroadcastSubscribers=0x7fffffff <3>
spring.integration.taskScheduler.poolSize=10 <4>
spring.integration.messagingTemplate.throwExceptionOnLateReply=false <5>
spring.integration.readOnly.headers= <6>
+spring.integration.endpoints.noAutoStartup= <7>
----
<1> When true, `input-channel` s will be automatically declared as `DirectChannel` s when not explicitly found in the
@@ -244,6 +245,10 @@ expecting a reply - because the sending thread has timed out, or already receive
The list is used by the `DefaultMessageBuilderFactory` bean and propagated to the `IntegrationMessageHeaderAccessor` instances (see <>), used to build messages via `MessageBuilder` (see <>).
By default only `MessageHeaders.ID` and `MessageHeaders.TIMESTAMP` are not copied during message building.
_Since version 4.3.2_
+<7> A comma-separated list of `AbstractEndpoint` bean names patterns (`xxx*`, `*xxx`, `*xxx*` or `xxx*yyy`) which should not be started automatically during application startup.
+These endpoints can be started later manually by their bean name via `Control Bus` (see <>), by their role using the `SmartLifecycleRoleController` (see <>) or via simple `Lifecycle` bean injection.
+The effect of this global property can be explicitly overridden by specifying `auto-startup` XML or `autoStartup` annotation attribute, or via call to the `AbstractEndpoint.setAutoStartup()` in bean definition.
+_Since version 4.3.12_
These properties can be overridden by adding a file `/META-INF/spring.integration.properties` to the classpath.
It is not necessary to provide all the properties, just those that you want to override.