diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java index 0d4c2d39b7b..a3cc7fc51c8 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodAnnotationPublisherMetadataSource.java @@ -17,20 +17,21 @@ package org.springframework.integration.aop; import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; import java.lang.reflect.Method; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import java.util.stream.Collectors; import org.springframework.core.LocalVariableTableParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer; -import org.springframework.core.annotation.AnnotatedElementUtils; -import org.springframework.core.annotation.AnnotationUtils; +import org.springframework.core.annotation.MergedAnnotation; +import org.springframework.core.annotation.MergedAnnotations; import org.springframework.expression.Expression; import org.springframework.integration.annotation.Publisher; +import org.springframework.lang.Nullable; import org.springframework.messaging.handler.annotation.Header; import org.springframework.messaging.handler.annotation.Payload; import org.springframework.util.Assert; @@ -80,143 +81,105 @@ public void setChannelAttributeName(String channelAttributeName) { @Override public String getChannelName(Method method) { - return this.channels.computeIfAbsent(method, method1 -> { - String channelName = getAnnotationValue(method, this.channelAttributeName, String.class); - if (channelName == null) { - channelName = getAnnotationValue(method.getDeclaringClass(), this.channelAttributeName, String.class); - } - return StringUtils.hasText(channelName) ? channelName : null; - }); - + return this.channels.computeIfAbsent(method, + method1 -> { + String channelName = getAnnotationValue(method, this.channelAttributeName); + if (channelName == null) { + channelName = getAnnotationValue(method.getDeclaringClass(), this.channelAttributeName); + } + return StringUtils.hasText(channelName) ? channelName : null; + }); } @Override public Expression getExpressionForPayload(Method method) { - return this.payloadExpressions.computeIfAbsent(method, method1 -> { - Expression payloadExpression = null; - Annotation methodPayloadAnnotation = AnnotationUtils.findAnnotation(method, Payload.class); - - if (methodPayloadAnnotation != null) { - String payloadExpressionString = getAnnotationValue(methodPayloadAnnotation, null, String.class); - if (!StringUtils.hasText(payloadExpressionString)) { - payloadExpression = RETURN_VALUE_EXPRESSION; - } - else { - payloadExpression = EXPRESSION_PARSER.parseExpression(payloadExpressionString); - } - } + return this.payloadExpressions.computeIfAbsent(method, + method1 -> { + Expression payloadExpression = null; + MergedAnnotation payloadMergedAnnotation = + MergedAnnotations.from(method, MergedAnnotations.SearchStrategy.EXHAUSTIVE) + .get(Payload.class); + if (payloadMergedAnnotation.isPresent()) { + String payloadExpressionString = payloadMergedAnnotation.getString("expression"); + if (!StringUtils.hasText(payloadExpressionString)) { + payloadExpression = RETURN_VALUE_EXPRESSION; + } + else { + payloadExpression = EXPRESSION_PARSER.parseExpression(payloadExpressionString); + } + } - Annotation[][] annotationArray = method.getParameterAnnotations(); - for (int i = 0; i < annotationArray.length; i++) { - Annotation[] parameterAnnotations = annotationArray[i]; - for (Annotation currentAnnotation : parameterAnnotations) { - if (Payload.class.equals(currentAnnotation.annotationType())) { - Assert.state(payloadExpression == null, - "@Payload can be used at most once on a @Publisher method, " + - "either at method-level or on a single parameter"); + Annotation[][] annotationArray = method.getParameterAnnotations(); + for (int i = 0; i < annotationArray.length; i++) { + Annotation[] parameterAnnotations = annotationArray[i]; + payloadMergedAnnotation = MergedAnnotations.from(parameterAnnotations).get(Payload.class); + if (payloadMergedAnnotation.isPresent()) { + Assert.state(payloadExpression == null, + "@Payload can be used at most once on a @Publisher method, " + + "either at method-level or on a single parameter"); - Assert.state("".equals(AnnotationUtils.getValue(AnnotationUtils.synthesizeAnnotation(currentAnnotation, null))), - "@Payload on a parameter for a @Publisher method may not contain an expression"); + Assert.state("".equals(payloadMergedAnnotation.getString("expression")), + "@Payload on a parameter for a @Publisher method may not contain an 'expression'"); - payloadExpression = - EXPRESSION_PARSER.parseExpression("#" + ARGUMENT_MAP_VARIABLE_NAME + "[" + i + "]"); + payloadExpression = + EXPRESSION_PARSER.parseExpression("#" + ARGUMENT_MAP_VARIABLE_NAME + "[" + i + "]"); + } } - } - } - if (payloadExpression == null || - RETURN_VALUE_EXPRESSION.getExpressionString().equals(payloadExpression.getExpressionString())) { - Assert.isTrue(!void.class.equals(method.getReturnType()), - "When defining @Publisher on a void-returning method, an explicit payload " + - "expression that does not rely upon a #return value is required."); - } - return payloadExpression; - }); - } - - @Override - @Deprecated - public String getPayloadExpression(Method method) { - return getExpressionForPayload(method) - .getExpressionString(); + if (payloadExpression == null || + RETURN_VALUE_EXPRESSION.getExpressionString() + .equals(payloadExpression.getExpressionString())) { + Assert.isTrue(!void.class.equals(method.getReturnType()), + "When defining @Publisher on a void-returning method, an explicit payload " + + "expression that does not rely upon a #return value is required."); + } + return payloadExpression; + }); } @Override public Map getExpressionsForHeaders(Method method) { - return this.headersExpressions.computeIfAbsent(method, method1 -> { - Map headerExpressions = new HashMap<>(); - String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method); - Annotation[][] annotationArray = method.getParameterAnnotations(); - for (int i = 0; i < annotationArray.length; i++) { - Annotation[] parameterAnnotations = annotationArray[i]; - for (Annotation currentAnnotation : parameterAnnotations) { - if (Header.class.equals(currentAnnotation.annotationType())) { - String name = getAnnotationValue(currentAnnotation, null, String.class); - if (!StringUtils.hasText(name)) { - name = parameterNames[i]; + return this.headersExpressions.computeIfAbsent(method, + method1 -> { + Map headerExpressions = new HashMap<>(); + String[] parameterNames = this.parameterNameDiscoverer.getParameterNames(method); + Annotation[][] annotationArray = method.getParameterAnnotations(); + for (int i = 0; i < annotationArray.length; i++) { + Annotation[] parameterAnnotations = annotationArray[i]; + MergedAnnotation
headerMergedAnnotation = + MergedAnnotations.from(parameterAnnotations).get(Header.class); + if (headerMergedAnnotation.isPresent()) { + String name = + headerMergedAnnotation + .getString("name"); + if (!StringUtils.hasText(name)) { + if (parameterNames != null) { + name = parameterNames[i]; + } + else { + name = method.getName() + ".arg#" + i; + } + } + headerExpressions.put(name, + EXPRESSION_PARSER.parseExpression('#' + ARGUMENT_MAP_VARIABLE_NAME + '[' + i + ']')); } - headerExpressions.put(name, - EXPRESSION_PARSER.parseExpression("#" + ARGUMENT_MAP_VARIABLE_NAME + "[" + i + "]")); } - } - } - return headerExpressions; - }); + return headerExpressions; + }); } - @Override - @Deprecated - public Map getHeaderExpressions(Method method) { - return getExpressionsForHeaders(method) - .entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, e -> e.getValue().getExpressionString())); - } - - private T getAnnotationValue(Method method, String attributeName, Class expectedType) { - T value = null; + @Nullable + private String getAnnotationValue(AnnotatedElement element, String attributeName) { + MergedAnnotations mergedAnnotations = + MergedAnnotations.from(element, MergedAnnotations.SearchStrategy.EXHAUSTIVE); + String value = null; for (Class annotationType : this.annotationTypes) { - Annotation annotation = AnnotatedElementUtils.findMergedAnnotation(method, annotationType); - if (annotation != null) { + MergedAnnotation mergedAnnotation = mergedAnnotations.get(annotationType); + if (mergedAnnotation.isPresent()) { if (value != null) { throw new IllegalStateException( - "method [" + method + "] contains more than one publisher annotation"); + "The [" + element + "] contains more than one publisher annotation"); } - value = getAnnotationValue(annotation, attributeName, expectedType); - } - } - return value; - } - - private T getAnnotationValue(Class clazz, String attributeName, Class expectedType) { - T value = null; - for (Class annotationType : this.annotationTypes) { - Annotation annotation = AnnotatedElementUtils.findMergedAnnotation(clazz, annotationType); - if (annotation != null) { - if (value != null) { - throw new IllegalStateException( - "class [" + clazz + "] contains more than one publisher annotation"); - } - value = getAnnotationValue(annotation, attributeName, expectedType); - } - } - return value; - } - - @SuppressWarnings("unchecked") - private T getAnnotationValue(Annotation annotation, String attributeName, Class expectedType) { - T value = null; - Object valueAsObject = (attributeName == null) ? - AnnotationUtils.getValue(AnnotationUtils.synthesizeAnnotation(annotation, null)) : - AnnotationUtils.getValue(annotation, attributeName); - - if (valueAsObject != null) { - if (expectedType.isAssignableFrom(valueAsObject.getClass())) { - value = (T) valueAsObject; - } - else { - throw new IllegalArgumentException("expected type [" + expectedType.getName() + - "] for attribute '" + attributeName + "' on publisher annotation [" + - annotation.annotationType() + "], but actual type was [" + valueAsObject.getClass() + "]"); + value = mergedAnnotation.getString(attributeName); } } return value; diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodNameMappingPublisherMetadataSource.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodNameMappingPublisherMetadataSource.java index b5181c7b51b..a15dfbff7d9 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodNameMappingPublisherMetadataSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/MethodNameMappingPublisherMetadataSource.java @@ -77,24 +77,6 @@ public Expression getExpressionForPayload(Method method) { return null; } - @Override - @Deprecated - public String getPayloadExpression(Method method) { - Expression expressionForPayload = getExpressionForPayload(method); - return expressionForPayload != null ? expressionForPayload.getExpressionString() : null; - } - - @Override - @Deprecated - public Map getHeaderExpressions(Method method) { - Map expressionsForHeaders = getExpressionsForHeaders(method); - return expressionsForHeaders == null - ? null - : expressionsForHeaders.entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, entry -> entry.getValue().getExpressionString())); - } - @Override public Map getExpressionsForHeaders(Method method) { return this.headerExpressionMap diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherMetadataSource.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherMetadataSource.java index 7cc17cee3ca..422337e0715 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherMetadataSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/PublisherMetadataSource.java @@ -18,7 +18,6 @@ import java.lang.reflect.Method; import java.util.Map; -import java.util.stream.Collectors; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; @@ -59,16 +58,6 @@ interface PublisherMetadataSource { */ String getChannelName(Method method); - /** - * Returns the expression string to be evaluated for creating the Message - * payload. - * @param method The Method. - * @return The payload expression. - * @deprecated since 5.0.4 in favor of {@link #getExpressionForPayload(Method)} - */ - @Deprecated - String getPayloadExpression(Method method); - /** * Returns the SpEL expression to be evaluated for creating the Message * payload. @@ -76,21 +65,7 @@ interface PublisherMetadataSource { * @return rhe payload expression. * @since 5.0.4 */ - @SuppressWarnings("deprecation") - default Expression getExpressionForPayload(Method method) { - return EXPRESSION_PARSER.parseExpression(getPayloadExpression(method)); - } - - /** - * Returns the map of expression strings to be evaluated for any headers - * that should be set on the published Message. The keys in the Map are - * header names, the values are the expression strings. - * @param method The Method. - * @return The header expressions. - * @deprecated since 5.0.4 in favor of {@link #getExpressionsForHeaders(Method)} - */ - @Deprecated - Map getHeaderExpressions(Method method); + Expression getExpressionForPayload(Method method); /** * Returns the map of expression strings to be evaluated for any headers @@ -99,13 +74,6 @@ default Expression getExpressionForPayload(Method method) { * @param method The Method. * @return The header expressions. */ - @SuppressWarnings("deprecation") - default Map getExpressionsForHeaders(Method method) { - return getHeaderExpressions(method) - .entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, - e -> EXPRESSION_PARSER.parseExpression(e.getValue()))); - } + Map getExpressionsForHeaders(Method method); } diff --git a/spring-integration-core/src/main/java/org/springframework/integration/aop/SimplePublisherMetadataSource.java b/spring-integration-core/src/main/java/org/springframework/integration/aop/SimplePublisherMetadataSource.java index 0e9baa40851..0813371f857 100644 --- a/spring-integration-core/src/main/java/org/springframework/integration/aop/SimplePublisherMetadataSource.java +++ b/spring-integration-core/src/main/java/org/springframework/integration/aop/SimplePublisherMetadataSource.java @@ -54,12 +54,6 @@ public void setPayloadExpression(String payloadExpression) { this.payloadExpression = EXPRESSION_PARSER.parseExpression(payloadExpression); } - @Override - @Deprecated - public String getPayloadExpression(Method method) { - return this.payloadExpression.getExpressionString(); - } - @Override public Expression getExpressionForPayload(Method method) { return this.payloadExpression; @@ -73,16 +67,6 @@ public void setHeaderExpressions(Map headerExpressions) { e -> EXPRESSION_PARSER.parseExpression(e.getValue()))); } - @Override - @Deprecated - public Map getHeaderExpressions(Method method) { - return this.headerExpressions - .entrySet() - .stream() - .collect(Collectors.toMap(Map.Entry::getKey, - e -> e.getValue().getExpressionString())); - } - @Override public Map getExpressionsForHeaders(Method method) { return this.headerExpressions; diff --git a/spring-integration-core/src/test/java/org/springframework/integration/aop/MessagePublishingInterceptorTests.java b/spring-integration-core/src/test/java/org/springframework/integration/aop/MessagePublishingInterceptorTests.java index 4d5fc5dd1f6..02827712fb4 100644 --- a/spring-integration-core/src/test/java/org/springframework/integration/aop/MessagePublishingInterceptorTests.java +++ b/spring-integration-core/src/test/java/org/springframework/integration/aop/MessagePublishingInterceptorTests.java @@ -73,15 +73,16 @@ public void returnValue() { @Test public void demoMethodNameMappingExpressionSource() { - Map expressionMap = new HashMap(); + Map expressionMap = new HashMap<>(); expressionMap.put("test", "#return"); - MethodNameMappingPublisherMetadataSource metadataSource = new MethodNameMappingPublisherMetadataSource(expressionMap); - Map channelMap = new HashMap(); + MethodNameMappingPublisherMetadataSource metadataSource = + new MethodNameMappingPublisherMetadataSource(expressionMap); + Map channelMap = new HashMap<>(); channelMap.put("test", "c"); metadataSource.setChannelMap(channelMap); - Map> headerExpressionMap = new HashMap>(); - Map headerExpressions = new HashMap(); + Map> headerExpressionMap = new HashMap<>(); + Map headerExpressions = new HashMap<>(); headerExpressions.put("bar", "#return"); headerExpressions.put("name", "'oleg'"); headerExpressionMap.put("test", headerExpressions); @@ -125,24 +126,11 @@ private static class TestPublisherMetadataSource implements PublisherMetadataSou super(); } - @Override - @Deprecated - public String getPayloadExpression(Method method) { - return getExpressionForPayload(method) - .getExpressionString(); - } - @Override public Expression getExpressionForPayload(Method method) { return EXPRESSION_PARSER.parseExpression("'test-' + #return"); } - @Override - @Deprecated - public Map getHeaderExpressions(Method method) { - return null; - } - @Override public Map getExpressionsForHeaders(Method method) { return null;