INT-4326: Add endpoints.noAutoStartup property
JIRA: https://jira.spring.io/browse/INT-4326 To let to disable autoStartup for particular endpoint bean globally, in one place, add `spring.integration.endpoints.noAutoStartup` to the `spring.integration.properties` So, now all the `AbstractEndpoint` checks that property for matching its bean name to configure `autoStartup` property to `false` **Cherry-pick to 4.3.x** Conflicts: spring-integration-core/src/main/resources/META-INF/spring.integration.default.properties spring-integration-core/src/test/resources/META-INF/spring.integration.properties src/reference/asciidoc/configuration.adoc Resolved.
This commit is contained in:
committed by
Gary Russell
parent
c877b041d4
commit
d8ecdce83d
@@ -71,7 +71,7 @@ public class ConsumerEndpointFactoryBean
|
||||
|
||||
private volatile PollerMetadata pollerMetadata;
|
||||
|
||||
private volatile boolean autoStartup = true;
|
||||
private volatile Boolean autoStartup;
|
||||
|
||||
private volatile int phase = 0;
|
||||
|
||||
@@ -133,7 +133,7 @@ public class ConsumerEndpointFactoryBean
|
||||
this.beanClassLoader = classLoader;
|
||||
}
|
||||
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
public void setAutoStartup(Boolean autoStartup) {
|
||||
this.autoStartup = autoStartup;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,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");
|
||||
}
|
||||
}
|
||||
@@ -287,7 +289,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;
|
||||
|
||||
@@ -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 {
|
||||
@@ -81,6 +82,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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -7,3 +7,4 @@ spring.integration.messagingAnnotations.require.componentAnnotation=false
|
||||
spring.integration.messagingGateway.convertReceiveMessage=false
|
||||
# Defaults to MessageHeaders.ID and MessageHeaders.TIMESTAMP
|
||||
spring.integration.readOnly.headers=
|
||||
spring.integration.endpoints.noAutoStartup=
|
||||
|
||||
@@ -11,4 +11,7 @@
|
||||
|
||||
<service-activator id="fooService" input-channel="foo" output-channel="nullChannel" expression="'foo'"/>
|
||||
|
||||
<service-activator id="fooServiceExplicit" input-channel="foo" output-channel="nullChannel" expression="'foo'"
|
||||
auto-startup="true"/>
|
||||
|
||||
</beans:beans>
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,3 +4,4 @@
|
||||
spring.integration.taskScheduler.poolSize=20
|
||||
spring.integration.messagingTemplate.throwExceptionOnLateReply=true
|
||||
spring.integration.readOnly.headers=contentType
|
||||
spring.integration.endpoints.noAutoStartup=fooService*
|
||||
|
||||
@@ -206,6 +206,8 @@ spring.integration.channels.maxBroadcastSubscribers=0x7fffffff <3>
|
||||
spring.integration.taskScheduler.poolSize=10 <4>
|
||||
spring.integration.messagingTemplate.throwExceptionOnLateReply=false <5>
|
||||
spring.integration.messagingAnnotations.require.componentAnnotation=false <6>
|
||||
spring.integration.readOnly.headers= <7>
|
||||
spring.integration.endpoints.noAutoStartup= <8>
|
||||
----
|
||||
|
||||
<1> When true, `input-channel` s will be automatically declared as `DirectChannel` s when not explicitly found in the
|
||||
@@ -226,6 +228,14 @@ expecting a reply - because the sending thread has timed out, or already receive
|
||||
|
||||
<6> When `true`, Messaging Annotation Support (<<annotations>>) requires a declaration of the
|
||||
`@MessageEndpoint` (or any other `@Component`) annotation on the class level.
|
||||
<7> A comma-separated list of message header names which should not be populated into `Message` s during a header copying operation.
|
||||
The list is used by the `DefaultMessageBuilderFactory` bean and propagated to the `IntegrationMessageHeaderAccessor` instances (see <<message-header-accessor>>), used to build messages via `MessageBuilder` (see <<message-builder>>).
|
||||
By default only `MessageHeaders.ID` and `MessageHeaders.TIMESTAMP` are not copied during message building.
|
||||
_Since version 4.3.2_
|
||||
<8> 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 <<control-bus>>), by their role using the `SmartLifecycleRoleController` (see <<endpoint-roles>>) 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.
|
||||
|
||||
Reference in New Issue
Block a user