diff --git a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java index d4affa3fdf9..7577482f2e9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/config/DefaultConfiguringBeanFactoryPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 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. @@ -67,6 +67,7 @@ import org.springframework.integration.support.converter.DefaultDatatypeChannelMessageConverter; import org.springframework.integration.support.json.JacksonPresent; import org.springframework.integration.support.utils.IntegrationUtils; +import org.springframework.messaging.handler.annotation.support.DefaultMessageHandlerMethodFactory; import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; import org.springframework.util.ClassUtils; @@ -122,8 +123,8 @@ public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) registerGlobalChannelInterceptorProcessor(); registerDefaultDatatypeChannelMessageConverter(); registerArgumentResolverMessageConverter(); - registerArgumentResolvers(); - registerListCapableArgumentResolvers(); + registerMessageHandlerMethodFactory(); + registerListMessageHandlerMethodFactory(); } else if (logger.isWarnEnabled()) { logger.warn("BeanFactory is not a BeanDefinitionRegistry. " + @@ -479,32 +480,32 @@ private void registerArgumentResolverMessageConverter() { } } - /** - * Register the default - * {@link org.springframework.integration.handler.support.HandlerMethodArgumentResolversHolder} for handler - * method invocation. - */ - private void registerArgumentResolvers() { - if (!this.beanFactory.containsBean(IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME)) { - this.registry.registerBeanDefinition(IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME, - internalArgumentResolversBuilder(false)); + private void registerMessageHandlerMethodFactory() { + if (!this.beanFactory.containsBean(IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME)) { + BeanDefinitionBuilder messageHandlerMethodFactoryBuilder = + createMessageHandlerMethodFactoryBeanDefinition(false); + this.registry.registerBeanDefinition(IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME, + messageHandlerMethodFactoryBuilder.getBeanDefinition()); } } - /** - * Register the default - * {@link org.springframework.integration.handler.support.HandlerMethodArgumentResolversHolder} for handler - * method invocation for lists. - */ - private void registerListCapableArgumentResolvers() { - if (!this.beanFactory.containsBean(IntegrationContextUtils.LIST_ARGUMENT_RESOLVERS_BEAN_NAME)) { - this.registry.registerBeanDefinition(IntegrationContextUtils.LIST_ARGUMENT_RESOLVERS_BEAN_NAME, - internalArgumentResolversBuilder(true)); + private void registerListMessageHandlerMethodFactory() { + if (!this.beanFactory.containsBean(IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME)) { + BeanDefinitionBuilder messageHandlerMethodFactoryBuilder = + createMessageHandlerMethodFactoryBeanDefinition(true); + this.registry.registerBeanDefinition(IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME, + messageHandlerMethodFactoryBuilder.getBeanDefinition()); } } - @SuppressWarnings("deprecation") - private BeanDefinition internalArgumentResolversBuilder(boolean listCapable) { + private BeanDefinitionBuilder createMessageHandlerMethodFactoryBeanDefinition(boolean listCapable) { + return BeanDefinitionBuilder.genericBeanDefinition(DefaultMessageHandlerMethodFactory.class) + .addPropertyReference("messageConverter", + IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME) + .addPropertyValue("customArgumentResolvers", buildArgumentResolvers(listCapable)); + } + + private ManagedList buildArgumentResolvers(boolean listCapable) { ManagedList resolvers = new ManagedList<>(); resolvers.add(new RootBeanDefinition(PayloadExpressionArgumentResolver.class)); BeanDefinitionBuilder builder = @@ -513,7 +514,6 @@ private BeanDefinition internalArgumentResolversBuilder(boolean listCapable) { // TODO Validator ? resolvers.add(builder.getBeanDefinition()); resolvers.add(new RootBeanDefinition(PayloadsArgumentResolver.class)); - resolvers.add(new RootBeanDefinition(MapArgumentResolver.class)); if (listCapable) { resolvers.add( @@ -522,10 +522,8 @@ private BeanDefinition internalArgumentResolversBuilder(boolean listCapable) { .getBeanDefinition()); } - return BeanDefinitionBuilder.genericBeanDefinition( - org.springframework.integration.handler.support.HandlerMethodArgumentResolversHolder.class) - .addConstructorArgValue(resolvers) - .getBeanDefinition(); + resolvers.add(new RootBeanDefinition(MapArgumentResolver.class)); + return resolvers; } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java index 38ad03e02a6..3b8c8b93437 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/context/IntegrationContextUtils.java @@ -101,14 +101,12 @@ public abstract class IntegrationContextUtils { public static final String ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME = "integrationArgumentResolverMessageConverter"; - public static final String ARGUMENT_RESOLVERS_BEAN_NAME = "integrationArgumentResolvers"; - - public static final String LIST_ARGUMENT_RESOLVERS_BEAN_NAME = "integrationListArgumentResolvers"; - public static final String DISPOSABLES_BEAN_NAME = "integrationDisposableAutoCreatedBeans"; public static final String MESSAGE_HANDLER_FACTORY_BEAN_NAME = "integrationMessageHandlerMethodFactory"; + public static final String LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME = "integrationListMessageHandlerMethodFactory"; + /** * @param beanFactory BeanFactory for lookup, must not be null. * @return The {@link MetadataStore} bean whose name is "metadataStore". diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionCommandMessageProcessor.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionCommandMessageProcessor.java index 8d4847f8556..e76eb100868 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionCommandMessageProcessor.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/ExpressionCommandMessageProcessor.java @@ -61,7 +61,7 @@ public ExpressionCommandMessageProcessor(@Nullable MethodFilter methodFilter, @N } if (methodFilter != null) { MethodResolver methodResolver = new ExpressionCommandMethodResolver(methodFilter); - getEvaluationContext(false).setMethodResolvers(Collections.singletonList(methodResolver)); + getEvaluationContext().setMethodResolvers(Collections.singletonList(methodResolver)); } } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/HandlerMethodArgumentResolversHolder.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/HandlerMethodArgumentResolversHolder.java deleted file mode 100644 index 8f29286dc13..00000000000 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/HandlerMethodArgumentResolversHolder.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2017-2019 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.integration.handler.support; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.messaging.handler.invocation.HandlerMethodArgumentResolver; - -/** - * A holder for the configured argument resolvers. - * - * @author Gary Russell - * - * @since 5.0 - * @deprecated as of 5.1.2. Instead simply configure your own MessageHandlerMethodFactory as a bean. - */ -@Deprecated -public class HandlerMethodArgumentResolversHolder { - - private final List resolvers; - - public HandlerMethodArgumentResolversHolder(List resolvers) { - this.resolvers = new ArrayList<>(resolvers); - } - - public List getResolvers() { - return Collections.unmodifiableList(this.resolvers); - } - - public void addResolver(HandlerMethodArgumentResolver resolver) { - this.resolvers.add(resolver); - } - - public boolean removeResolver(HandlerMethodArgumentResolver resolver) { - return this.resolvers.remove(resolver); - } - -} diff --git a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MessagingMethodInvokerHelper.java b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MessagingMethodInvokerHelper.java index a4893b191bb..f082b4bb77d 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MessagingMethodInvokerHelper.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/handler/support/MessagingMethodInvokerHelper.java @@ -43,7 +43,6 @@ import org.springframework.aop.framework.Advised; import org.springframework.aop.support.AopUtils; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.beans.factory.config.ConfigurableBeanFactory; @@ -56,7 +55,6 @@ import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.convert.ConversionFailedException; -import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.TypeDescriptor; import org.springframework.expression.EvaluationException; @@ -341,8 +339,6 @@ public void setUseSpelInvoker(boolean useSpelInvoker) { @Override public void setBeanFactory(BeanFactory beanFactory) { super.setBeanFactory(beanFactory); - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory).setBeanFactory(beanFactory); - if (beanFactory instanceof ConfigurableListableBeanFactory) { BeanExpressionResolver beanExpressionResolver = ((ConfigurableListableBeanFactory) beanFactory) .getBeanExpressionResolver(); @@ -353,15 +349,6 @@ public void setBeanFactory(BeanFactory beanFactory) { } } - @Override - public void setConversionService(ConversionService conversionService) { - super.setConversionService(conversionService); - if (conversionService != null) { - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory) - .setConversionService(conversionService); - } - } - @Nullable public Object process(Message message) { ParametersWrapper parameters = new ParametersWrapper(message); @@ -398,20 +385,9 @@ public boolean isRunning() { return !(this.targetObject instanceof Lifecycle) || ((Lifecycle) this.targetObject).isRunning(); } - /* - * Private constructors for internal use - */ - - private boolean isProvidedMessageHandlerFactoryBean() { - BeanFactory beanFactory = getBeanFactory(); - return beanFactory != null - && beanFactory.containsBean(IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME); - } - private HandlerMethod createHandlerMethod(Method method) { try { - InvocableHandlerMethod invocableHandlerMethod = createInvocableHandlerMethod(method); - HandlerMethod newHandlerMethod = new HandlerMethod(invocableHandlerMethod, this.canProcessMessageList); + HandlerMethod newHandlerMethod = new HandlerMethod(method, this.canProcessMessageList); checkSpelInvokerRequired(getTargetClass(this.targetObject), method, newHandlerMethod); return newHandlerMethod; } @@ -438,7 +414,7 @@ else if (targetMethod instanceof String) { } private void prepareEvaluationContext() { - StandardEvaluationContext context = getEvaluationContext(false); + StandardEvaluationContext context = getEvaluationContext(); Class targetType = AopUtils.getTargetClass(this.targetObject); if (this.method != null) { context.registerMethodFilter(targetType, new FixedMethodFilter(this.method)); @@ -471,13 +447,12 @@ private boolean canReturnExpectedType(AnnotatedMethodFilter filter, Class tar if (this.expectedType == null) { return true; } + List methods = filter.filter(Arrays.asList(ReflectionUtils.getAllDeclaredMethods(targetType))); - for (Method candidate : methods) { - if (typeConverter.canConvert(TypeDescriptor.valueOf(candidate.getReturnType()), this.expectedType)) { - return true; - } - } - return false; + return methods + .stream() + .anyMatch(candidate -> + typeConverter.canConvert(TypeDescriptor.valueOf(candidate.getReturnType()), this.expectedType)); } @Nullable @@ -493,18 +468,16 @@ private Object processInternal(ParametersWrapper parameters) { if (!candidate.initialized) { initializeHandler(candidate); } - Expression expression = candidate.expression; - Object result; if (this.useSpelInvoker || candidate.spelOnly) { - result = invokeExpression(expression, parameters); + result = invokeExpression(candidate.expression, parameters); } else { result = invokeHandlerMethod(candidate, parameters); } if (result != null && this.expectedType != null) { - return getEvaluationContext(true) + return getEvaluationContext() .getTypeConverter() .convertValue(result, TypeDescriptor.forObject(result), this.expectedType); } @@ -513,129 +486,94 @@ private Object processInternal(ParametersWrapper parameters) { } } - private void initializeHandler(HandlerMethod candidate) { - ExpressionParser parser; - if (candidate.useSpelInvoker == null) { - parser = EXPRESSION_PARSER_DEFAULT; + private synchronized void initialize() { + if (isProvidedMessageHandlerFactoryBean()) { + LOGGER.info("Overriding default instance of MessageHandlerMethodFactory with provided one."); + this.messageHandlerMethodFactory = + getBeanFactory() + .getBean( + this.canProcessMessageList + ? IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME + : IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME, + MessageHandlerMethodFactory.class); } else { - String compilerMode = resolveExpression(candidate.useSpelInvoker.compilerMode(), - "UseSpelInvoker.compilerMode:").toUpperCase(); - parser = !StringUtils.hasText(compilerMode) - ? EXPRESSION_PARSER_DEFAULT - : SPEL_COMPILERS.get(SpelCompilerMode.valueOf(compilerMode)); + configureLocalMessageHandlerFactory(); } - candidate.expression = parser.parseExpression(candidate.expressionString); - candidate.initialized = true; - } - @SuppressWarnings("deprecation") - private synchronized void initialize() { - if (!this.initialized) { - BeanFactory beanFactory = getBeanFactory(); - if (isProvidedMessageHandlerFactoryBean()) { - LOGGER.info("Overriding default instance of MessageHandlerMethodFactory with provided one."); - this.messageHandlerMethodFactory = - beanFactory.getBean(IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME, - MessageHandlerMethodFactory.class); - this.handlerMethodsList - .stream() - .map(Map::values) - .flatMap(Collection::stream) - .forEach(handlerMethod -> - handlerMethod.replaceInvocableHandlerMethod( - createInvocableHandlerMethod(handlerMethod.invocableHandlerMethod.getMethod()))); - } - else { - if (beanFactory != null && - beanFactory.containsBean( - IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)) { - - try { - MessageConverter messageConverter = - beanFactory.getBean( - IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME, - MessageConverter.class); - - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory) - .setMessageConverter(messageConverter); - - HandlerMethodArgumentResolversHolder handlerMethodArgumentResolversHolder = - beanFactory.getBean(this.canProcessMessageList - ? IntegrationContextUtils.LIST_ARGUMENT_RESOLVERS_BEAN_NAME - : IntegrationContextUtils.ARGUMENT_RESOLVERS_BEAN_NAME, - HandlerMethodArgumentResolversHolder.class); - - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory) - .setCustomArgumentResolvers( - handlerMethodArgumentResolversHolder.getResolvers()); - } - catch (NoSuchBeanDefinitionException e) { - configureLocalMessageHandlerFactory(); - } - } - else { - configureLocalMessageHandlerFactory(); - } - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory).afterPropertiesSet(); - } + prepareEvaluationContext(); + this.initialized = true; + } - prepareEvaluationContext(); - this.initialized = true; - } + private boolean isProvidedMessageHandlerFactoryBean() { + BeanFactory beanFactory = getBeanFactory(); + return beanFactory != null + && beanFactory.containsBean( + this.canProcessMessageList + ? IntegrationContextUtils.LIST_MESSAGE_HANDLER_FACTORY_BEAN_NAME + : IntegrationContextUtils.MESSAGE_HANDLER_FACTORY_BEAN_NAME); } /* * This should not be needed in production but we have many tests * that don't run in an application context. */ - private void configureLocalMessageHandlerFactory() { - MessageConverter messageConverter = null; - BeanFactory beanFactory = getBeanFactory(); - if (beanFactory != null && - beanFactory.containsBean(IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME)) { - messageConverter = beanFactory - .getBean(IntegrationContextUtils.ARGUMENT_RESOLVER_MESSAGE_CONVERTER_BEAN_NAME, - MessageConverter.class); - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory) - .setMessageConverter(messageConverter); + + private void initializeHandler(HandlerMethod candidate) { + ExpressionParser parser; + if (candidate.useSpelInvoker == null) { + parser = EXPRESSION_PARSER_DEFAULT; } else { - messageConverter = new ConfigurableCompositeMessageConverter(); + String compilerMode = resolveExpression(candidate.useSpelInvoker.compilerMode()).toUpperCase(); + parser = !StringUtils.hasText(compilerMode) + ? EXPRESSION_PARSER_DEFAULT + : SPEL_COMPILERS.get(SpelCompilerMode.valueOf(compilerMode)); } - NullAwarePayloadArgumentResolver nullResolver = new NullAwarePayloadArgumentResolver(messageConverter); - PayloadExpressionArgumentResolver payloadExpressionArgumentResolver = new PayloadExpressionArgumentResolver(); - if (beanFactory != null) { - payloadExpressionArgumentResolver.setBeanFactory(beanFactory); + candidate.expression = parser.parseExpression(candidate.expressionString); + if (!this.useSpelInvoker && !candidate.spelOnly) { + candidate.setInvocableHandlerMethod(createInvocableHandlerMethod(candidate.method)); } + candidate.initialized = true; + } - PayloadsArgumentResolver payloadsArgumentResolver = new PayloadsArgumentResolver(); - if (beanFactory != null) { - payloadsArgumentResolver.setBeanFactory(beanFactory); - } + private void configureLocalMessageHandlerFactory() { + BeanFactory beanFactory = getBeanFactory(); - MapArgumentResolver mapArgumentResolver = new MapArgumentResolver(); - if (beanFactory != null) { - mapArgumentResolver.setBeanFactory(beanFactory); - } + MessageConverter messageConverter = new ConfigurableCompositeMessageConverter(); List customArgumentResolvers = new LinkedList<>(); + PayloadExpressionArgumentResolver payloadExpressionArgumentResolver = new PayloadExpressionArgumentResolver(); + PayloadsArgumentResolver payloadsArgumentResolver = new PayloadsArgumentResolver(); + customArgumentResolvers.add(payloadExpressionArgumentResolver); - customArgumentResolvers.add(nullResolver); + customArgumentResolvers.add(new NullAwarePayloadArgumentResolver(messageConverter)); customArgumentResolvers.add(payloadsArgumentResolver); + CollectionArgumentResolver collectionArgumentResolver = null; + if (this.canProcessMessageList) { - CollectionArgumentResolver collectionArgumentResolver = new CollectionArgumentResolver(true); - if (beanFactory != null) { - collectionArgumentResolver.setBeanFactory(beanFactory); - } + collectionArgumentResolver = new CollectionArgumentResolver(true); customArgumentResolvers.add(collectionArgumentResolver); } + MapArgumentResolver mapArgumentResolver = new MapArgumentResolver(); customArgumentResolvers.add(mapArgumentResolver); - ((DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory) - .setCustomArgumentResolvers(customArgumentResolvers); + if (beanFactory != null) { + payloadExpressionArgumentResolver.setBeanFactory(beanFactory); + payloadsArgumentResolver.setBeanFactory(beanFactory); + mapArgumentResolver.setBeanFactory(beanFactory); + if (collectionArgumentResolver != null) { + collectionArgumentResolver.setBeanFactory(beanFactory); + } + } + + DefaultMessageHandlerMethodFactory localHandlerMethodFactory = + (DefaultMessageHandlerMethodFactory) this.messageHandlerMethodFactory; + localHandlerMethodFactory.setMessageConverter(messageConverter); + localHandlerMethodFactory.setCustomArgumentResolvers(customArgumentResolvers); + localHandlerMethodFactory.afterPropertiesSet(); } private Object invokeHandlerMethod(HandlerMethod handlerMethod, ParametersWrapper parameters) { @@ -943,27 +881,20 @@ private void populateHandlerMethod(Map, HandlerMethod> candidateMethods @Nullable private Method obtainFrameworkMethod(Class targetClass) { - Method frameworkMethod = null; for (Class iface : ClassUtils.getAllInterfacesForClass(targetClass)) { try { // Can't use real class because of package tangle if ("org.springframework.integration.gateway.RequestReplyExchanger".equals(iface.getName())) { - frameworkMethod = - ClassUtils.getMostSpecificMethod( - targetClass.getMethod("exchange", Message.class), - this.targetObject.getClass()); - if (LOGGER.isDebugEnabled()) { - LOGGER.debug(this.targetObject.getClass() + - ": Ambiguous fallback methods; using RequestReplyExchanger.exchange()"); - } - break; + return ClassUtils.getMostSpecificMethod( + targetClass.getMethod("exchange", Message.class), + this.targetObject.getClass()); } } catch (Exception ex) { throw new IllegalStateException(ex); } } - return frameworkMethod; + return null; } private void findSingleSpecifMethodOnInterfacesIfProxy(Map, HandlerMethod> candidateMessageMethods, @@ -1026,7 +957,7 @@ private void checkSpelInvokerRequired(final Class targetClass, Method methodA } } - private String resolveExpression(String value, String msg) { + private String resolveExpression(String value) { String resolvedValue = resolve(value); if (!(resolvedValue.startsWith("#{") && value.endsWith("}"))) { @@ -1034,7 +965,7 @@ private String resolveExpression(String value, String msg) { } Object evaluated = this.resolver.evaluate(resolvedValue, this.expressionContext); - Assert.isInstanceOf(String.class, evaluated, msg); + Assert.isInstanceOf(String.class, evaluated, "UseSpelInvoker.compilerMode:"); return (String) evaluated; } @@ -1125,21 +1056,23 @@ private static class HandlerMethod { private final boolean canProcessMessageList; + private final Method method; + private InvocableHandlerMethod invocableHandlerMethod; - private volatile Expression expression; + private Expression expression; - private volatile TypeDescriptor targetParameterTypeDescriptor; + private TypeDescriptor targetParameterTypeDescriptor; - private volatile Class targetParameterType = Void.class; + private Class targetParameterType = Void.class; private MethodParameter exclusiveMethodParameter; - private volatile boolean messageMethod; + private boolean messageMethod; - private volatile boolean spelOnly; + private UseSpelInvoker useSpelInvoker; - private volatile UseSpelInvoker useSpelInvoker; + private volatile boolean spelOnly; private volatile boolean initialized; @@ -1148,13 +1081,13 @@ private static class HandlerMethod { // Switching to spelOnly afterwards forever. private volatile int failedAttempts = 0; - HandlerMethod(InvocableHandlerMethod invocableHandlerMethod, boolean canProcessMessageList) { - this.invocableHandlerMethod = invocableHandlerMethod; + HandlerMethod(Method method, boolean canProcessMessageList) { + this.method = method; this.canProcessMessageList = canProcessMessageList; - this.expressionString = generateExpression(this.invocableHandlerMethod.getMethod()); + this.expressionString = generateExpression(this.method); } - void replaceInvocableHandlerMethod(InvocableHandlerMethod newInvocableHandlerMethod) { + void setInvocableHandlerMethod(InvocableHandlerMethod newInvocableHandlerMethod) { this.invocableHandlerMethod = newInvocableHandlerMethod; } @@ -1184,7 +1117,7 @@ private boolean isMessageMethod() { @Override public String toString() { - return this.invocableHandlerMethod.toString(); + return this.method.toString(); } private String generateExpression(Method method) { diff --git a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java index aa714fcf2c5..ac39012ea73 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/config/annotation/AggregatorAnnotationTests.java @@ -107,8 +107,7 @@ public void testAnnotationWithCustomCorrelationStrategy() throws Exception { Object handlerMethod = processorAccessor.getPropertyValue("handlerMethod"); assertThat(handlerMethod).isNotNull(); DirectFieldAccessor handlerMethodAccessor = new DirectFieldAccessor(handlerMethod); - Method completionCheckerMethod = (Method) handlerMethodAccessor.getPropertyValue( - "invocableHandlerMethod.method"); + Method completionCheckerMethod = (Method) handlerMethodAccessor.getPropertyValue("method"); assertThat(completionCheckerMethod.getName()).isEqualTo("correlate"); context.close(); } diff --git a/spring-integration-core/src/test/java/org/springframework/integration/transformer/MethodInvokingTransformerTests.java b/spring-integration-core/src/test/java/org/springframework/integration/transformer/MethodInvokingTransformerTests.java index 65efd64c79e..2907c0f7959 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/transformer/MethodInvokingTransformerTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/transformer/MethodInvokingTransformerTests.java @@ -17,12 +17,13 @@ package org.springframework.integration.transformer; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.mockito.Mockito.mock; import java.lang.reflect.Method; import java.util.Properties; -import org.junit.Test; +import org.junit.jupiter.api.Test; import org.springframework.beans.factory.BeanFactory; import org.springframework.integration.annotation.Transformer; @@ -37,10 +38,10 @@ * @author Mark Fisher * @author Artem Bilan */ -public class MethodInvokingTransformerTests { +class MethodInvokingTransformerTests { @Test - public void simplePayloadConfiguredWithMethodReference() throws Exception { + void simplePayloadConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("exclaim", String.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -51,7 +52,7 @@ public void simplePayloadConfiguredWithMethodReference() throws Exception { } @Test - public void simplePayloadConfiguredWithMethodName() { + void simplePayloadConfiguredWithMethodName() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "exclaim"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -61,7 +62,7 @@ public void simplePayloadConfiguredWithMethodName() { } @Test - public void typeConversionConfiguredWithMethodReference() throws Exception { + void typeConversionConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("exclaim", String.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -72,7 +73,7 @@ public void typeConversionConfiguredWithMethodReference() throws Exception { } @Test - public void typeConversionConfiguredWithMethodName() { + void typeConversionConfiguredWithMethodName() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "exclaim"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -81,25 +82,8 @@ public void typeConversionConfiguredWithMethodName() { assertThat(result.getPayload()).isEqualTo("123!"); } - @Test(expected = MessageHandlingException.class) - public void typeConversionFailureConfiguredWithMethodReference() throws Exception { - TestBean testBean = new TestBean(); - Method testMethod = testBean.getClass().getMethod("exclaim", String.class); - MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); - Message message = new GenericMessage(new TestBean()); - transformer.transform(message); - } - - @Test(expected = MessageHandlingException.class) - public void typeConversionFailureConfiguredWithMethodName() { - TestBean testBean = new TestBean(); - MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "exclaim"); - Message message = new GenericMessage<>(new TestBean()); - transformer.transform(message); - } - @Test - public void headerAnnotationConfiguredWithMethodReference() throws Exception { + void headerAnnotationConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("headerTest", String.class, Integer.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -111,7 +95,7 @@ public void headerAnnotationConfiguredWithMethodReference() throws Exception { } @Test - public void headerAnnotationConfiguredWithMethodName() { + void headerAnnotationConfiguredWithMethodName() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "headerTest"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -121,18 +105,19 @@ public void headerAnnotationConfiguredWithMethodName() { assertThat(result.getPayload()).isEqualTo("foo123"); } - @Test(expected = MessageHandlingException.class) - public void headerValueNotProvided() throws Exception { + @Test + void headerValueNotProvided() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("headerTest", String.class, Integer.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); Message message = MessageBuilder.withPayload("foo") .setHeader("wrong", 123).build(); - transformer.transform(message); + assertThatExceptionOfType(MessageHandlingException.class) + .isThrownBy(() -> transformer.transform(message)); } @Test - public void optionalHeaderAnnotation() throws Exception { + void optionalHeaderAnnotation() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("optionalHeaderTest", String.class, Integer.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -143,7 +128,7 @@ public void optionalHeaderAnnotation() throws Exception { } @Test - public void optionalHeaderValueNotProvided() throws Exception { + void optionalHeaderValueNotProvided() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("optionalHeaderTest", String.class, Integer.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -154,7 +139,7 @@ public void optionalHeaderValueNotProvided() throws Exception { } @Test - public void messageReturnValueConfiguredWithMethodReference() throws Exception { + void messageReturnValueConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("messageReturnValueTest", Message.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -165,7 +150,7 @@ public void messageReturnValueConfiguredWithMethodReference() throws Exception { } @Test - public void messageReturnValueConfiguredWithMethodName() { + void messageReturnValueConfiguredWithMethodName() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "messageReturnValueTest"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -176,7 +161,7 @@ public void messageReturnValueConfiguredWithMethodName() { @Test @SuppressWarnings("unchecked") - public void propertiesPayloadConfiguredWithMethodReference() throws Exception { + void propertiesPayloadConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("propertyPayloadTest", Properties.class); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, testMethod); @@ -198,7 +183,7 @@ public void propertiesPayloadConfiguredWithMethodReference() throws Exception { @Test @SuppressWarnings("unchecked") - public void propertiesPayloadConfiguredWithMethodName() { + void propertiesPayloadConfiguredWithMethodName() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "propertyPayloadTest"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -218,7 +203,7 @@ public void propertiesPayloadConfiguredWithMethodName() { } @Test - public void nullReturningMethod() { + void nullReturningMethod() { TestBean testBean = new TestBean(); MethodInvokingTransformer transformer = new MethodInvokingTransformer(testBean, "nullReturnValueTest"); transformer.setBeanFactory(mock(BeanFactory.class)); @@ -228,8 +213,9 @@ public void nullReturningMethod() { } @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test // this changed in 2.0 see INT-785 and INT-1130 - public void headerEnricherConfiguredWithMethodReference() throws Exception { + @Test + // this changed in 2.0 see INT-785 and INT-1130 + void headerEnricherConfiguredWithMethodReference() throws Exception { TestBean testBean = new TestBean(); Method testMethod = testBean.getClass().getMethod("propertyEnricherTest", String.class); HeaderEnricher transformer = new HeaderEnricher(); @@ -248,8 +234,9 @@ public void headerEnricherConfiguredWithMethodReference() throws Exception { } @SuppressWarnings({ "rawtypes", "unchecked" }) - @Test // this changed in 2.0 see INT-785 and INT-1130 - public void headerEnricherConfiguredWithMethodName() { + @Test + // this changed in 2.0 see INT-785 and INT-1130 + void headerEnricherConfiguredWithMethodName() { TestBean testBean = new TestBean(); HeaderEnricher transformer = new HeaderEnricher(); MethodInvokingMessageProcessor processor =