Short-circuit methods for lambdas from annotation (#2823)
* Short-circuit methods for lambdas from annotation When we have a `@ServiceActivator` or any other messaging annotations on `Function` or `Consumer` `@Bean`s, there is a restriction when we can't use lambdas because of target method argument type erasure in Java. * Use a `@Bean` method return to determine the target function argument type and wrap the call into the `LambdaMessageProcessor`. In this case we call the target method directly after possible payload conversion according expected generic type for `Function` or `Consumer`. There is just no reason to go a `MessagingMethodInvokerHelper` route for this lambda variants * Apply the short-circuit algorithm for Kotlin lambdas as well * Make some refactoring and improvements to `ClassUtils` if favor or similar API in the SF `ClassUtils` * Fix `No beanFactory` warning for the `ExpressionCommandMessageProcessor` * * Resolve Checkstyle violations * * Fix `resolveAttributeToBoolean()` argument name to be generic * Fix typo in the exception message for `IntegrationFlowDefinition.get()` * * Revert `ClassUtils.resolvePrimitiveType()` logic: an existing in SF does exactly opposite one
This commit is contained in:
committed by
Gary Russell
parent
a599881a8e
commit
572dc0ec14
@@ -349,8 +349,7 @@ public class MessagingAnnotationsWithBeanAnnotationTests {
|
||||
@Filter(inputChannel = "skippedChannel5")
|
||||
@Profile("foo")
|
||||
public MessageHandler skippedMessageHandler() {
|
||||
return m -> {
|
||||
};
|
||||
return m -> { };
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -384,14 +383,7 @@ public class MessagingAnnotationsWithBeanAnnotationTests {
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "functionMessageServiceChannel")
|
||||
public Function<Message<String>, String> messageFunctionAsService() {
|
||||
return new Function<Message<String>, String>() { // Has to be interface for proper type inferring
|
||||
|
||||
@Override
|
||||
public String apply(Message<String> m) {
|
||||
return m.getPayload().toLowerCase();
|
||||
}
|
||||
|
||||
};
|
||||
return (message) -> message.getPayload().toLowerCase();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@@ -408,14 +400,7 @@ public class MessagingAnnotationsWithBeanAnnotationTests {
|
||||
@Bean
|
||||
@ServiceActivator(inputChannel = "messageConsumerServiceChannel")
|
||||
public Consumer<Message<?>> messageConsumerAsService() {
|
||||
return new Consumer<Message<?>>() { // Has to be interface for proper type inferring
|
||||
|
||||
@Override
|
||||
public void accept(Message<?> e) {
|
||||
collector().add(e);
|
||||
}
|
||||
|
||||
};
|
||||
return collector()::add;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.integration.function
|
||||
|
||||
import assertk.all
|
||||
import assertk.assertThat
|
||||
import assertk.assertions.isEqualTo
|
||||
import assertk.assertions.isNotNull
|
||||
@@ -24,8 +23,10 @@ import assertk.assertions.isTrue
|
||||
import assertk.assertions.size
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.springframework.beans.factory.annotation.Autowired
|
||||
import org.springframework.beans.factory.annotation.Qualifier
|
||||
import org.springframework.context.annotation.Bean
|
||||
import org.springframework.context.annotation.Configuration
|
||||
import org.springframework.integration.annotation.EndpointId
|
||||
import org.springframework.integration.annotation.InboundChannelAdapter
|
||||
import org.springframework.integration.annotation.Poller
|
||||
import org.springframework.integration.annotation.ServiceActivator
|
||||
@@ -37,6 +38,7 @@ import org.springframework.integration.dsl.IntegrationFlows
|
||||
import org.springframework.integration.endpoint.SourcePollingChannelAdapter
|
||||
import org.springframework.messaging.Message
|
||||
import org.springframework.messaging.MessageChannel
|
||||
import org.springframework.messaging.PollableChannel
|
||||
import org.springframework.messaging.SubscribableChannel
|
||||
import org.springframework.messaging.support.GenericMessage
|
||||
import org.springframework.messaging.support.MessageBuilder
|
||||
@@ -44,9 +46,7 @@ import org.springframework.test.annotation.DirtiesContext
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig
|
||||
import java.util.*
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.Executors
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.function.Supplier
|
||||
|
||||
/**
|
||||
* @author Artem Bilan
|
||||
@@ -70,8 +70,12 @@ class FunctionsTests {
|
||||
private lateinit var counterChannel: SubscribableChannel
|
||||
|
||||
@Autowired
|
||||
@Qualifier("kotlinSupplierChannelAdapter")
|
||||
private lateinit var kotlinSupplierInboundChannelAdapter: SourcePollingChannelAdapter
|
||||
|
||||
@Autowired
|
||||
private lateinit var fromSupplierQueue: PollableChannel
|
||||
|
||||
@Test
|
||||
fun `invoke function via transformer`() {
|
||||
val replyChannel = QueueChannel()
|
||||
@@ -111,6 +115,11 @@ class FunctionsTests {
|
||||
assertThat(countDownLatch.await(10, TimeUnit.SECONDS)).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `verify supplier flow`() {
|
||||
assertThat(this.fromSupplierQueue.receive(10_000)).isNotNull()
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableIntegration
|
||||
class Config {
|
||||
@@ -136,10 +145,23 @@ class FunctionsTests {
|
||||
@Bean
|
||||
@InboundChannelAdapter(value = "counterChannel", autoStartup = "false",
|
||||
poller = [Poller(fixedRate = "10", maxMessagesPerPoll = "1")])
|
||||
@EndpointId("kotlinSupplierChannelAdapter")
|
||||
fun kotlinSupplier(): () -> String {
|
||||
return { "baz" }
|
||||
}
|
||||
|
||||
@Bean
|
||||
fun flowFromSupplier() =
|
||||
IntegrationFlows.from<String>({ "bar" },
|
||||
{ e ->
|
||||
e.poller { p ->
|
||||
p.fixedDelay(10)
|
||||
.maxMessagesPerPoll(1)
|
||||
}
|
||||
|
||||
})
|
||||
.channel { c -> c.queue("fromSupplierQueue") }
|
||||
.get()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user