GH-8586: Deprecate IntegrationComponentSpec.get() (#8594)

* GH-8586: Deprecate IntegrationComponentSpec.get()

Fixes https://github.com/spring-projects/spring-integration/issues/8586

The `IntegrationComponentSpec` is not a plain wrapper around single component.
Sometimes it comes with several components where all of them must be registered
as beans.
If `IntegrationComponentSpec.get()` is called from end-user code, we may lose
other related components, for example filters in the `FileInboundChannelAdapterSpec`.

* Deprecate `IntegrationComponentSpec.get()` with no-op for end-user,
rather encourage to leave it as is and let the framework take care about its lifecycle
and related components registration
* Fix `IntegrationComponentSpec` logic to deal as a simple `FactoryBean` instead of
extra overhead via `AbstractFactoryBean`
* Use `IntegrationComponentSpec.getObject()` in the framework code where `get()` was called
* Fix tests to expose `IntegrationComponentSpec` as beans instead of previously called `get()`
* Some other clean up and typos fixes in the affected classes
* Document the change

* * Revert `ObjectStringMapBuilder` in the `KafkaInboundGatewaySpec.getComponentsToRegister()`

* Fix language in docs

Co-authored-by: Gary Russell <grussell@vmware.com>

* * Remove trailing whitespace in the `ScriptMessageSourceSpec`

---------

Co-authored-by: Gary Russell <grussell@vmware.com>
This commit is contained in:
Artem Bilan
2023-04-13 09:16:42 -04:00
committed by GitHub
parent bbaffb22bf
commit b99729544d
46 changed files with 401 additions and 369 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 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.
@@ -19,7 +19,6 @@ package org.springframework.integration.dsl;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
@@ -233,7 +232,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* at the current {@link IntegrationFlow} chain position.
* The provided {@code messageChannelName} is used for the bean registration
* ({@link org.springframework.integration.channel.DirectChannel}), if there is no such a bean
* in the application context. Otherwise the existing {@link MessageChannel} bean is used
* in the application context. Otherwise, the existing {@link MessageChannel} bean is used
* to wire integration endpoints.
* @param messageChannelName the bean name to use.
* @return the current {@link BaseIntegrationFlowDefinition}.
@@ -252,7 +251,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
*/
public B channel(MessageChannelSpec<?, ?> messageChannelSpec) {
Assert.notNull(messageChannelSpec, "'messageChannelSpec' must not be null");
return channel(messageChannelSpec.get());
return channel(messageChannelSpec.getObject());
}
/**
@@ -367,7 +366,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param wireTapChannel the {@link MessageChannel} bean name to wire-tap.
* @return the current {@link BaseIntegrationFlowDefinition}.
*/
@@ -377,8 +376,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@code Wire Tap} EI Pattern specific
* {@link org.springframework.messaging.support.ChannelInterceptor} implementation
* to the current {@link #currentMessageChannel}.
* {@link ChannelInterceptor} implementation to the current {@link #currentMessageChannel}.
* It is useful when an implicit {@link MessageChannel} is used between endpoints:
* <pre class="code">
* {@code
@@ -388,7 +386,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param wireTapChannel the {@link MessageChannel} to wire-tap.
* @return the current {@link BaseIntegrationFlowDefinition}.
*/
@@ -398,8 +396,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@code Wire Tap} EI Pattern specific
* {@link org.springframework.messaging.support.ChannelInterceptor} implementation
* to the current {@link #currentMessageChannel}.
* {@link ChannelInterceptor} implementation to the current {@link #currentMessageChannel}.
* It is useful when an implicit {@link MessageChannel} is used between endpoints:
* <pre class="code">
* {@code
@@ -409,7 +406,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param flow the {@link IntegrationFlow} for wire-tap subflow as an alternative to the {@code wireTapChannel}.
* @param wireTapConfigurer the {@link Consumer} to accept options for the {@link WireTap}.
* @return the current {@link BaseIntegrationFlowDefinition}.
@@ -438,8 +435,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@code Wire Tap} EI Pattern specific
* {@link org.springframework.messaging.support.ChannelInterceptor} implementation
* to the current {@link #currentMessageChannel}.
* {@link ChannelInterceptor} implementation to the current {@link #currentMessageChannel}.
* It is useful when an implicit {@link MessageChannel} is used between endpoints:
* <pre class="code">
* {@code
@@ -449,7 +445,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param wireTapChannel the {@link MessageChannel} bean name to wire-tap.
* @param wireTapConfigurer the {@link Consumer} to accept options for the {@link WireTap}.
* @return the current {@link BaseIntegrationFlowDefinition}.
@@ -462,8 +458,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@code Wire Tap} EI Pattern specific
* {@link org.springframework.messaging.support.ChannelInterceptor} implementation
* to the current {@link #currentMessageChannel}.
* {@link ChannelInterceptor} implementation to the current {@link #currentMessageChannel}.
* It is useful when an implicit {@link MessageChannel} is used between endpoints:
* <pre class="code">
* {@code
@@ -473,7 +468,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param wireTapChannel the {@link MessageChannel} to wire-tap.
* @param wireTapConfigurer the {@link Consumer} to accept options for the {@link WireTap}.
* @return the current {@link BaseIntegrationFlowDefinition}.
@@ -489,8 +484,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@code Wire Tap} EI Pattern specific
* {@link org.springframework.messaging.support.ChannelInterceptor} implementation
* to the current {@link #currentMessageChannel}.
* {@link ChannelInterceptor} implementation to the current {@link #currentMessageChannel}.
* <p> It is useful when an implicit {@link MessageChannel} is used between endpoints:
* <pre class="code">
* {@code
@@ -500,14 +494,16 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
* }
* </pre>
* This method can be used after any {@link #channel} for explicit {@link MessageChannel},
* but with the caution do not impact existing {@link org.springframework.messaging.support.ChannelInterceptor}s.
* but with the caution do not impact existing {@link ChannelInterceptor}s.
* @param wireTapSpec the {@link WireTapSpec} to use.
* <p> When this EIP-method is used in the end of flow, it appends {@code nullChannel} to terminate flow properly,
* Otherwise {@code Dispatcher has no subscribers} exception is thrown for implicit {@link DirectChannel}.
* <p> When this EIP-method is used in the end of flow,
* it appends a {@code nullChannel} to terminate flow properly,
* Otherwise a {@code Dispatcher has no subscribers} exception
* is thrown for implicit {@link DirectChannel}.
* @return the current {@link BaseIntegrationFlowDefinition}.
*/
public B wireTap(WireTapSpec wireTapSpec) {
WireTap interceptor = wireTapSpec.get();
WireTap interceptor = wireTapSpec.getObject();
InterceptableChannel currentChannel = currentInterceptableChannel();
addComponent(wireTapSpec);
currentChannel.addInterceptor(interceptor);
@@ -613,7 +609,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@link MessageTransformingHandler} instance for the
* {@link org.springframework.integration.handler.MessageProcessor} from provided {@link MessageProcessorSpec}.
* {@link MessageProcessor} from provided {@link MessageProcessorSpec}.
* <pre class="code">
* {@code
* .transform(Scripts.script("classpath:myScript.py").variable("foo", bar()))
@@ -629,7 +625,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
/**
* Populate the {@link MessageTransformingHandler} instance for the
* {@link org.springframework.integration.handler.MessageProcessor} from provided {@link MessageProcessorSpec}.
* {@link MessageProcessor} from provided {@link MessageProcessorSpec}.
* In addition, accept options for the integration endpoint using {@link GenericEndpointSpec}.
* <pre class="code">
* {@code
@@ -646,7 +642,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
Consumer<GenericEndpointSpec<MessageTransformingHandler>> endpointConfigurer) {
Assert.notNull(messageProcessorSpec, MESSAGE_PROCESSOR_SPEC_MUST_NOT_BE_NULL);
MessageProcessor<?> processor = messageProcessorSpec.get();
MessageProcessor<?> processor = messageProcessorSpec.getObject();
return addComponent(processor)
.transform(null, new MethodInvokingTransformer(processor), endpointConfigurer);
}
@@ -832,7 +828,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
*/
public B filter(MessageProcessorSpec<?> messageProcessorSpec, Consumer<FilterEndpointSpec> endpointConfigurer) {
Assert.notNull(messageProcessorSpec, MESSAGE_PROCESSOR_SPEC_MUST_NOT_BE_NULL);
MessageProcessor<?> processor = messageProcessorSpec.get();
MessageProcessor<?> processor = messageProcessorSpec.getObject();
return addComponent(processor)
.filter(null, new MethodInvokingSelector(processor), endpointConfigurer);
}
@@ -1089,7 +1085,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
Consumer<GenericEndpointSpec<ServiceActivatingHandler>> endpointConfigurer) {
Assert.notNull(messageProcessorSpec, MESSAGE_PROCESSOR_SPEC_MUST_NOT_BE_NULL);
MessageProcessor<?> processor = messageProcessorSpec.get();
MessageProcessor<?> processor = messageProcessorSpec.getObject();
return addComponent(processor)
.handle(new ServiceActivatingHandler(processor), endpointConfigurer);
}
@@ -1118,7 +1114,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
if (messageHandlerSpec instanceof ComponentsRegistration) {
addComponents(((ComponentsRegistration) messageHandlerSpec).getComponentsToRegister());
}
return handle(messageHandlerSpec.get(), endpointConfigurer);
return handle(messageHandlerSpec.getObject(), endpointConfigurer);
}
/**
@@ -1287,7 +1283,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
HeaderEnricherSpec headerEnricherSpec = new HeaderEnricherSpec();
headerEnricherSpec.headers(headers);
Tuple2<ConsumerEndpointFactoryBean, MessageTransformingHandler> tuple2 = headerEnricherSpec.get();
Tuple2<ConsumerEndpointFactoryBean, MessageTransformingHandler> tuple2 = headerEnricherSpec.getObject();
return addComponents(headerEnricherSpec.getComponentsToRegister())
.handle(tuple2.getT2(), endpointConfigurer);
}
@@ -1478,7 +1474,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
Consumer<SplitterEndpointSpec<MethodInvokingSplitter>> endpointConfigurer) {
Assert.notNull(messageProcessorSpec, MESSAGE_PROCESSOR_SPEC_MUST_NOT_BE_NULL);
MessageProcessor<?> processor = messageProcessorSpec.get();
MessageProcessor<?> processor = messageProcessorSpec.getObject();
return addComponent(processor)
.split(new MethodInvokingSplitter(processor), endpointConfigurer);
}
@@ -1569,7 +1565,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
public <S extends AbstractMessageSplitter> B split(MessageHandlerSpec<?, S> splitterMessageHandlerSpec,
Consumer<SplitterEndpointSpec<S>> endpointConfigurer) {
Assert.notNull(splitterMessageHandlerSpec, "'splitterMessageHandlerSpec' must not be null");
return split(splitterMessageHandlerSpec.get(), endpointConfigurer);
return split(splitterMessageHandlerSpec.getObject(), endpointConfigurer);
}
/**
@@ -1960,7 +1956,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
Consumer<RouterSpec<Object, MethodInvokingRouter>> routerConfigurer) {
Assert.notNull(messageProcessorSpec, MESSAGE_PROCESSOR_SPEC_MUST_NOT_BE_NULL);
MessageProcessor<?> processor = messageProcessorSpec.get();
MessageProcessor<?> processor = messageProcessorSpec.getObject();
addComponent(processor);
return route(new RouterSpec<>(new MethodInvokingRouter(processor)), routerConfigurer);
@@ -2713,7 +2709,7 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
if (gatherer != null) {
gatherer.accept(aggregatorSpec);
}
AggregatingMessageHandler aggregatingMessageHandler = aggregatorSpec.get().getT2();
AggregatingMessageHandler aggregatingMessageHandler = aggregatorSpec.getObject().getT2();
addComponent(aggregatingMessageHandler);
ScatterGatherHandler messageHandler = new ScatterGatherHandler(scatterChannel, aggregatingMessageHandler);
return register(new ScatterGatherSpec(messageHandler), scatterGather);
@@ -2766,10 +2762,10 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
if (gatherer != null) {
gatherer.accept(aggregatorSpec);
}
RecipientListRouter recipientListRouter = recipientListRouterSpec.get().getT2();
RecipientListRouter recipientListRouter = recipientListRouterSpec.getObject().getT2();
addComponent(recipientListRouter)
.addComponents(recipientListRouterSpec.getComponentsToRegister());
AggregatingMessageHandler aggregatingMessageHandler = aggregatorSpec.get().getT2();
AggregatingMessageHandler aggregatingMessageHandler = aggregatorSpec.getObject().getT2();
addComponent(aggregatingMessageHandler);
ScatterGatherHandler messageHandler = new ScatterGatherHandler(recipientListRouter, aggregatingMessageHandler);
return register(new ScatterGatherSpec(messageHandler), scatterGather);
@@ -2974,16 +2970,16 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
this.registerOutputChannelIfCan(inputChannel);
}
Tuple2<ConsumerEndpointFactoryBean, ? extends MessageHandler> factoryBeanTuple2 = endpointSpec.get();
Tuple2<ConsumerEndpointFactoryBean, ? extends MessageHandler> factoryBeanTuple2 = endpointSpec.getObject();
addComponents(endpointSpec.getComponentsToRegister());
if (inputChannel instanceof MessageChannelReference) {
factoryBeanTuple2.getT1().setInputChannelName(((MessageChannelReference) inputChannel).getName());
if (inputChannel instanceof MessageChannelReference messageChannelReference) {
factoryBeanTuple2.getT1().setInputChannelName(messageChannelReference.getName());
}
else {
if (inputChannel instanceof FixedSubscriberChannelPrototype) {
String beanName = ((FixedSubscriberChannelPrototype) inputChannel).getName();
if (inputChannel instanceof FixedSubscriberChannelPrototype fixedSubscriberChannel) {
String beanName = fixedSubscriberChannel.getName();
inputChannel = new FixedSubscriberChannel(factoryBeanTuple2.getT2());
if (beanName != null) {
((FixedSubscriberChannel) inputChannel).setBeanName(beanName);
@@ -3002,8 +2998,8 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
Object currComponent = getCurrentComponent();
if (currComponent != null) {
String channelName = null;
if (outputChannel instanceof MessageChannelReference) {
channelName = ((MessageChannelReference) outputChannel).getName();
if (outputChannel instanceof MessageChannelReference channelReference) {
channelName = channelReference.getName();
}
if (currComponent instanceof MessageProducer messageProducer) {
@@ -3015,9 +3011,9 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
messageProducer.setOutputChannel(outputChannel);
}
}
else if (currComponent instanceof SourcePollingChannelAdapterSpec) {
else if (currComponent instanceof SourcePollingChannelAdapterSpec sourcePollingChannelAdapterSpec) {
SourcePollingChannelAdapterFactoryBean pollingChannelAdapterFactoryBean =
((SourcePollingChannelAdapterSpec) currComponent).get().getT1();
sourcePollingChannelAdapterSpec.getObject().getT1();
if (channelName != null) {
pollingChannelAdapterFactoryBean.setOutputChannelName(channelName);
}
@@ -3081,13 +3077,11 @@ public abstract class BaseIntegrationFlowDefinition<B extends BaseIntegrationFlo
}
if (isImplicitChannel()) {
Optional<Object> lastComponent =
components.keySet()
.stream()
.reduce((first, second) -> second);
if (lastComponent.get() instanceof WireTapSpec) {
bridge();
}
components.keySet()
.stream()
.reduce((first, second) -> second)
.filter(WireTapSpec.class::isInstance)
.ifPresent((wireTap) -> bridge());
}
this.integrationFlow = new StandardIntegrationFlow(components);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -86,7 +86,7 @@ public abstract class EndpointSpec<S extends EndpointSpec<S, F, H>, F extends Be
if (components != null) {
this.componentsToRegister.putAll(components);
}
return poller(pollerMetadataSpec.get());
return poller(pollerMetadataSpec.getObject());
}
/**

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -16,15 +16,21 @@
package org.springframework.integration.dsl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.AbstractFactoryBean;
import org.springframework.context.Lifecycle;
import org.springframework.context.SmartLifecycle;
import org.springframework.expression.spel.standard.SpelExpressionParser;
/**
* The common Builder abstraction. The {@link #get()} method returns the final component.
* The common Builder abstraction.
* If used as a bean definition, must be treated as an {@link FactoryBean},
* therefore its {@link #getObject()} method must not be called in the target configuration.
*
* @param <S> the target {@link IntegrationComponentSpec} implementation type.
* @param <T> the target type.
@@ -35,11 +41,12 @@ import org.springframework.expression.spel.standard.SpelExpressionParser;
*/
@IntegrationDsl
public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpec<S, T>, T>
extends AbstractFactoryBean<T>
implements SmartLifecycle {
implements FactoryBean<T>, InitializingBean, DisposableBean, SmartLifecycle {
protected static final SpelExpressionParser PARSER = new SpelExpressionParser();
protected final Log logger = LogFactory.getLog(getClass()); // NOSONAR - final
protected volatile T target; // NOSONAR
private String id;
@@ -61,8 +68,25 @@ public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpe
/**
* @return the configured component.
* @deprecated since 6.1 with no-op for end-user:
* the {@link #getObject()} is called by the framework at the appropriate phase.
*/
@Deprecated(since = "6.1", forRemoval = true)
public T get() {
return getObject();
}
@Override
public Class<?> getObjectType() {
return getObject().getClass();
}
/**
* !!! This method must not be called from the target configuration !!!
* @return the object backed by this factory bean.
*/
@Override
public T getObject() {
if (this.target == null) {
this.target = doGet();
}
@@ -70,69 +94,57 @@ public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpe
}
@Override
public Class<?> getObjectType() {
return get().getClass();
}
@Override
protected T createInstance() {
T instance = get();
if (instance instanceof InitializingBean) {
try {
((InitializingBean) instance).afterPropertiesSet();
}
catch (Exception e) {
throw new IllegalStateException("Cannot initialize bean: " + instance, e);
public void afterPropertiesSet() {
try {
if (this.target instanceof InitializingBean initializingBean) {
initializingBean.afterPropertiesSet();
}
}
return instance;
catch (Exception ex) {
throw new BeanInitializationException("Cannot initialize bean: " + this.target, ex);
}
}
@Override
protected void destroyInstance(T instance) {
if (instance instanceof DisposableBean) {
public void destroy() {
if (this.target instanceof DisposableBean disposableBean) {
try {
((DisposableBean) instance).destroy();
disposableBean.destroy();
}
catch (Exception e) {
throw new IllegalStateException("Cannot destroy bean: " + instance, e);
throw new IllegalStateException("Cannot destroy bean: " + this.target, e);
}
}
}
@Override
public void start() {
T instance = get();
if (instance instanceof Lifecycle) {
((Lifecycle) instance).start();
if (this.target instanceof Lifecycle lifecycle) {
lifecycle.start();
}
}
@Override
public void stop() {
T instance = get();
if (instance instanceof Lifecycle) {
((Lifecycle) instance).stop();
if (this.target instanceof Lifecycle lifecycle) {
lifecycle.stop();
}
}
@Override
public boolean isRunning() {
T instance = get();
return !(instance instanceof Lifecycle) || ((Lifecycle) instance).isRunning();
return !(this.target instanceof Lifecycle lifecycle) || lifecycle.isRunning();
}
@Override
public boolean isAutoStartup() {
T instance = get();
return instance instanceof SmartLifecycle && ((SmartLifecycle) instance).isAutoStartup();
return this.target instanceof SmartLifecycle lifecycle && lifecycle.isAutoStartup();
}
@Override
public void stop(Runnable callback) {
T instance = get();
if (instance instanceof SmartLifecycle) {
((SmartLifecycle) instance).stop(callback);
if (this.target instanceof SmartLifecycle lifecycle) {
lifecycle.stop(callback);
}
else {
callback.run();
@@ -141,9 +153,8 @@ public abstract class IntegrationComponentSpec<S extends IntegrationComponentSpe
@Override
public int getPhase() {
T instance = get();
if (instance instanceof SmartLifecycle) {
return ((SmartLifecycle) instance).getPhase();
if (this.target instanceof SmartLifecycle lifecycle) {
return lifecycle.getPhase();
}
else {
return 0;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -151,7 +151,7 @@ public interface IntegrationFlow {
*/
static IntegrationFlowBuilder from(MessageChannelSpec<?, ?> messageChannelSpec) {
Assert.notNull(messageChannelSpec, "'messageChannelSpec' must not be null");
return from(messageChannelSpec.get());
return from(messageChannelSpec.getObject());
}
/**
@@ -217,7 +217,7 @@ public interface IntegrationFlow {
Consumer<SourcePollingChannelAdapterSpec> endpointConfigurer) {
Assert.notNull(messageSourceSpec, "'messageSourceSpec' must not be null");
return from(messageSourceSpec.get(), endpointConfigurer, registerComponents(messageSourceSpec));
return from(messageSourceSpec.getObject(), endpointConfigurer, registerComponents(messageSourceSpec));
}
/**
@@ -321,7 +321,7 @@ public interface IntegrationFlow {
* @see MessageProducerSpec
*/
static IntegrationFlowBuilder from(MessageProducerSpec<?, ?> messageProducerSpec) {
return from(messageProducerSpec.get(), registerComponents(messageProducerSpec));
return from(messageProducerSpec.getObject(), registerComponents(messageProducerSpec));
}
/**
@@ -362,7 +362,7 @@ public interface IntegrationFlow {
* @since 6.0
*/
static IntegrationFlowBuilder from(MessagingGatewaySpec<?, ?> inboundGatewaySpec) {
return from(inboundGatewaySpec.get(), registerComponents(inboundGatewaySpec));
return from(inboundGatewaySpec.getObject(), registerComponents(inboundGatewaySpec));
}
/**
@@ -445,14 +445,14 @@ public interface IntegrationFlow {
"' must be declared as a bean in the application context");
Object lastIntegrationComponentFromOther =
integrationComponents.keySet().stream().reduce((prev, next) -> next).orElse(null);
if (lastIntegrationComponentFromOther instanceof MessageChannel) {
return from((MessageChannel) lastIntegrationComponentFromOther);
if (lastIntegrationComponentFromOther instanceof MessageChannel messageChannel) {
return from(messageChannel);
}
else if (lastIntegrationComponentFromOther instanceof ConsumerEndpointFactoryBean) {
MessageHandler handler = ((ConsumerEndpointFactoryBean) lastIntegrationComponentFromOther).getHandler();
else if (lastIntegrationComponentFromOther instanceof ConsumerEndpointFactoryBean factoryBean) {
MessageHandler handler = factoryBean.getHandler();
handler = extractProxyTarget(handler);
if (handler instanceof AbstractMessageProducingHandler) {
return buildFlowFromOutputChannel((AbstractMessageProducingHandler) handler);
if (handler instanceof AbstractMessageProducingHandler producingHandler) {
return buildFlowFromOutputChannel(producingHandler);
}
lastIntegrationComponentFromOther = handler; // for the exception message below
}
@@ -489,9 +489,9 @@ public interface IntegrationFlow {
}
private static IntegrationFlowBuilder registerComponents(Object spec) {
if (spec instanceof ComponentsRegistration) {
if (spec instanceof ComponentsRegistration componentsRegistration) {
return new IntegrationFlowBuilder()
.addComponents(((ComponentsRegistration) spec).getComponentsToRegister());
.addComponents(componentsRegistration.getComponentsToRegister());
}
return null;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2019 the original author or authors.
* Copyright 2016-2023 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.
@@ -100,7 +100,7 @@ public abstract class MessageChannelSpec<S extends MessageChannelSpec<S, C>, C e
* @see WireTap
*/
public S wireTap(WireTapSpec wireTapSpec) {
WireTap interceptor = wireTapSpec.get();
WireTap interceptor = wireTapSpec.getObject();
this.componentsToRegister.put(interceptor, null);
return interceptor(interceptor);
}

View File

@@ -31,11 +31,12 @@ import org.springframework.util.Assert;
* Registers {@link IntegrationFlowBeanPostProcessor} and checks if all
* {@link org.springframework.integration.dsl.IntegrationComponentSpec} are extracted to
* the target object using
* {@link org.springframework.integration.dsl.IntegrationComponentSpec#get()}.
* {@link org.springframework.integration.dsl.IntegrationComponentSpec#getObject()}.
*
* @author Artem Bilan
* @author Gary Russell
* @author Chris Bono
*
* @since 5.0
*
* @see org.springframework.integration.config.IntegrationConfigurationBeanFactoryPostProcessor

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -113,14 +113,14 @@ public class IntegrationFlowBeanPostProcessor
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof StandardIntegrationFlow) {
return processStandardIntegrationFlow((StandardIntegrationFlow) bean, beanName);
if (bean instanceof StandardIntegrationFlow standardIntegrationFlow) {
return processStandardIntegrationFlow(standardIntegrationFlow, beanName);
}
else if (bean instanceof IntegrationFlow) {
return processIntegrationFlowImpl((IntegrationFlow) bean, beanName);
else if (bean instanceof IntegrationFlow integrationFlow) {
return processIntegrationFlowImpl(integrationFlow, beanName);
}
if (bean instanceof IntegrationComponentSpec) {
processIntegrationComponentSpec(beanName, (IntegrationComponentSpec<?, ?>) bean);
if (bean instanceof IntegrationComponentSpec<?, ?> integrationComponentSpec) {
processIntegrationComponentSpec(beanName, integrationComponentSpec);
}
return bean;
}
@@ -156,8 +156,8 @@ public class IntegrationFlowBeanPostProcessor
for (Map.Entry<Object, String> entry : integrationComponents.entrySet()) {
Object component = entry.getKey();
if (component instanceof ConsumerEndpointSpec<?, ?> endpointSpec) {
MessageHandler messageHandler = endpointSpec.get().getT2();
ConsumerEndpointFactoryBean endpoint = endpointSpec.get().getT1();
MessageHandler messageHandler = endpointSpec.getObject().getT2();
ConsumerEndpointFactoryBean endpoint = endpointSpec.getObject().getT1();
String id = endpointSpec.getId();
if (id == null) {
@@ -177,8 +177,8 @@ public class IntegrationFlowBeanPostProcessor
registerComponent(endpoint, id, flowBeanName);
targetIntegrationComponents.put(endpoint, id);
}
else if (component instanceof MessageChannelReference) {
String channelBeanName = ((MessageChannelReference) component).getName();
else if (component instanceof MessageChannelReference messageChannelReference) {
String channelBeanName = messageChannelReference.getName();
if (!this.beanFactory.containsBean(channelBeanName)) {
DirectChannel directChannel = new DirectChannel();
registerComponent(directChannel, channelBeanName, flowBeanName);
@@ -196,7 +196,7 @@ public class IntegrationFlowBeanPostProcessor
generateBeanName(o.getKey(), flowNamePrefix, o.getValue(),
useFlowIdAsPrefix)));
}
SourcePollingChannelAdapterFactoryBean pollingChannelAdapterFactoryBean = spec.get().getT1();
SourcePollingChannelAdapterFactoryBean pollingChannelAdapterFactoryBean = spec.getObject().getT1();
String id = spec.getId();
if (id == null) {
id = generateBeanName(pollingChannelAdapterFactoryBean, flowNamePrefix, entry.getValue(),
@@ -209,12 +209,13 @@ public class IntegrationFlowBeanPostProcessor
registerComponent(pollingChannelAdapterFactoryBean, id, flowBeanName);
targetIntegrationComponents.put(pollingChannelAdapterFactoryBean, id);
MessageSource<?> messageSource = spec.get().getT2();
MessageSource<?> messageSource = spec.getObject().getT2();
if (noBeanPresentForComponent(messageSource, flowBeanName)) {
String messageSourceId = id + ".source";
if (messageSource instanceof NamedComponent
&& ((NamedComponent) messageSource).getComponentName() != null) {
messageSourceId = ((NamedComponent) messageSource).getComponentName();
if (messageSource instanceof NamedComponent namedComponent
&& namedComponent.getComponentName() != null) {
messageSourceId = namedComponent.getComponentName();
}
registerComponent(messageSource, messageSourceId, flowBeanName);
}
@@ -342,7 +343,7 @@ public class IntegrationFlowBeanPostProcessor
}
private void processIntegrationComponentSpec(String beanName, IntegrationComponentSpec<?, ?> bean) {
Object target = bean.get();
Object target = bean.getObject();
invokeBeanInitializationHooks(beanName, target);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -119,7 +119,7 @@ public class FluxMessageChannelTests {
@Test
void testFluxMessageChannelCleanUp() throws InterruptedException {
FluxMessageChannel flux = MessageChannels.flux().get();
FluxMessageChannel flux = MessageChannels.flux().getObject();
CountDownLatch finishLatch = new CountDownLatch(1);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 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.
@@ -35,19 +35,19 @@ public class PollersTests {
@Test
public void testDurations() {
PeriodicTrigger trigger = (PeriodicTrigger) Pollers.fixedDelay(Duration.ofMinutes(1L)).get().getTrigger();
PeriodicTrigger trigger = (PeriodicTrigger) Pollers.fixedDelay(Duration.ofMinutes(1L)).getObject().getTrigger();
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.isFixedRate()).isFalse();
trigger = (PeriodicTrigger) Pollers.fixedDelay(Duration.ofMinutes(1L), Duration.ofSeconds(10L))
.get().getTrigger();
.getObject().getTrigger();
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.getInitialDelayDuration()).isEqualTo(Duration.ofSeconds(10));
assertThat(trigger.isFixedRate()).isFalse();
trigger = (PeriodicTrigger) Pollers.fixedRate(Duration.ofMinutes(1L)).get().getTrigger();
trigger = (PeriodicTrigger) Pollers.fixedRate(Duration.ofMinutes(1L)).getObject().getTrigger();
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.isFixedRate()).isTrue();
trigger = (PeriodicTrigger) Pollers.fixedRate(Duration.ofMinutes(1L), Duration.ofSeconds(10L))
.get().getTrigger();
.getObject().getTrigger();
assertThat(trigger.getPeriodDuration()).isEqualTo(Duration.ofSeconds(60));
assertThat(trigger.getInitialDelayDuration()).isEqualTo(Duration.ofSeconds(10));
assertThat(trigger.isFixedRate()).isTrue();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2021-2022 the original author or authors.
* Copyright 2021-2023 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.
@@ -27,6 +27,7 @@ import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.PollerSpec;
import org.springframework.integration.dsl.Pollers;
import org.springframework.integration.dsl.context.IntegrationFlowContext;
import org.springframework.integration.scheduling.PollerMetadata;
@@ -142,8 +143,8 @@ public class IntegrationFlowCompositionTests {
public static class ContextConfiguration {
@Bean(PollerMetadata.DEFAULT_POLLER)
PollerMetadata defaultPoller() {
return Pollers.fixedDelay(100).get();
PollerSpec defaultPoller() {
return Pollers.fixedDelay(100);
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2016-2022 the original author or authors.
* Copyright 2016-2023 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.
@@ -54,13 +54,16 @@ import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.FixedSubscriberChannel;
import org.springframework.integration.channel.NullChannel;
import org.springframework.integration.channel.PublishSubscribeChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.context.IntegrationContextUtils;
import org.springframework.integration.core.GenericTransformer;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.dsl.PollerSpec;
import org.springframework.integration.dsl.Pollers;
import org.springframework.integration.dsl.QueueChannelSpec;
import org.springframework.integration.dsl.Transformers;
import org.springframework.integration.endpoint.AbstractEndpoint;
import org.springframework.integration.endpoint.EventDrivenConsumer;
@@ -575,8 +578,8 @@ public class IntegrationFlowTests {
}
@Bean(name = PollerMetadata.DEFAULT_POLLER)
public PollerMetadata poller() {
return Pollers.fixedRate(100).get();
public PollerSpec poller() {
return Pollers.fixedRate(100);
}
@Bean(name = IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME)
@@ -588,8 +591,8 @@ public class IntegrationFlowTests {
@Bean
public MessageChannel suppliedChannel() {
return MessageChannels.queue(10).get();
public QueueChannelSpec suppliedChannel() {
return MessageChannels.queue(10);
}
}
@@ -608,8 +611,8 @@ public class IntegrationFlowTests {
}
@Bean
public MessageChannel suppliedChannel2() {
return MessageChannels.queue(10).get();
public QueueChannelSpec suppliedChannel2() {
return MessageChannels.queue(10);
}
}
@@ -627,12 +630,12 @@ public class IntegrationFlowTests {
@Bean
public MessageChannel inputChannel() {
return MessageChannels.direct().get();
return new DirectChannel();
}
@Bean
public MessageChannel foo() {
return MessageChannels.publishSubscribe().get();
return new PublishSubscribeChannel();
}
}
@@ -682,7 +685,7 @@ public class IntegrationFlowTests {
@Bean
public MessageChannel publishSubscribeChannel() {
return MessageChannels.publishSubscribe().get();
return new PublishSubscribeChannel();
}
@Bean
@@ -784,8 +787,8 @@ public class IntegrationFlowTests {
private MethodInterceptor delayedAdvice;
@Bean
public QueueChannel successChannel() {
return MessageChannels.queue().get();
public QueueChannelSpec successChannel() {
return MessageChannels.queue();
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2019-2022 the original author or authors.
* Copyright 2019-2023 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.
@@ -36,7 +36,6 @@ import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.core.MessagingTemplate;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.gateway.GatewayProxyFactoryBean;
import org.springframework.integration.gateway.MessagingGatewaySupport;
import org.springframework.integration.gateway.MethodArgsHolder;
@@ -189,7 +188,7 @@ public class GatewayDslTests {
@Bean
public MessageChannel gatewayError() {
return MessageChannels.queue().get();
return new QueueChannel();
}

View File

@@ -30,12 +30,12 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.MessageRejectedException;
import org.springframework.integration.annotation.Transformer;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.integration.channel.FixedSubscriberChannel;
import org.springframework.integration.channel.QueueChannel;
import org.springframework.integration.codec.Codec;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.integration.dsl.Transformers;
import org.springframework.integration.handler.advice.AbstractRequestHandlerAdvice;
import org.springframework.integration.handler.advice.ExpressionEvaluatingRequestHandlerAdvice;
@@ -423,7 +423,7 @@ public class TransformerTests {
@Bean
public MessageChannel enricherReplyChannel() {
return MessageChannels.direct().get();
return new DirectChannel();
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2017-2022 the original author or authors.
* Copyright 2017-2023 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.
@@ -20,8 +20,7 @@ import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
@@ -32,6 +31,7 @@ import org.springframework.integration.annotation.GatewayHeader;
import org.springframework.integration.annotation.MessagingGateway;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.integration.config.EnableIntegration;
import org.springframework.integration.dsl.DirectChannelSpec;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.MessageChannels;
import org.springframework.messaging.Message;
@@ -39,7 +39,7 @@ import org.springframework.messaging.MessageChannel;
import org.springframework.messaging.MessageHeaders;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.messaging.support.ChannelInterceptor;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
import static org.assertj.core.api.Assertions.assertThat;
@@ -48,7 +48,7 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @since 5.0
*/
@RunWith(SpringRunner.class)
@SpringJUnitConfig
public class ContentTypeConversionTests {
@Autowired
@@ -91,7 +91,7 @@ public class ContentTypeConversionTests {
}
@Bean
public MessageChannel serviceChannel(final AtomicReference<Object> sendData) {
public DirectChannelSpec serviceChannel(AtomicReference<Object> sendData) {
return MessageChannels.direct()
.interceptor(new ChannelInterceptor() {
@@ -101,8 +101,7 @@ public class ContentTypeConversionTests {
return message;
}
})
.get();
});
}
@Bean

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020-2021 the original author or authors.
* Copyright 2020-2023 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.
@@ -231,7 +231,7 @@ class KotlinDslTests {
@Bean(PollerMetadata.DEFAULT_POLLER)
fun defaultPoller() =
Pollers.fixedDelay(100).maxMessagesPerPoll(1).get()
Pollers.fixedDelay(100).maxMessagesPerPoll(1)
@Bean
fun convertFlow() =