From 400749667aad7511f2e33fbd5b4a1f103619a554 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 26 Oct 2015 23:10:33 +0100 Subject: [PATCH] Polishing --- .../MethodInvocationProceedingJoinPoint.java | 8 +- .../annotation/AnnotatedElementUtils.java | 140 +++++------------- .../annotation/ResponseBodyEmitter.java | 35 ++--- .../mvc/method/annotation/SseEmitter.java | 2 +- 4 files changed, 62 insertions(+), 123 deletions(-) diff --git a/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java b/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java index d0f93ef87c..d6e43ec1fd 100644 --- a/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java +++ b/spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2015 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. @@ -243,6 +243,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, private String toString(boolean includeModifier, boolean includeReturnTypeAndArgs, boolean useLongReturnAndArgumentTypeName, boolean useLongTypeName) { + StringBuilder sb = new StringBuilder(); if (includeModifier) { sb.append(Modifier.toString(getModifiers())); @@ -262,8 +263,9 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, return sb.toString(); } - private void appendTypes(StringBuilder sb, Class[] types, - boolean includeArgs, boolean useLongReturnAndArgumentTypeName) { + private void appendTypes(StringBuilder sb, Class[] types, boolean includeArgs, + boolean useLongReturnAndArgumentTypeName) { + if (includeArgs) { for (int size = types.length, i = 0; i < size; i++) { appendType(sb, types[i], useLongReturnAndArgumentTypeName); diff --git a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java index a284755161..10c3a14006 100644 --- a/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java +++ b/spring-core/src/main/java/org/springframework/core/annotation/AnnotatedElementUtils.java @@ -101,10 +101,8 @@ public class AnnotatedElementUtils { * Get the fully qualified class names of all meta-annotation * types present on the annotation (of the specified * {@code annotationType}) on the supplied {@link AnnotatedElement}. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationType the annotation type on which to find * meta-annotations; never {@code null} @@ -123,10 +121,8 @@ public class AnnotatedElementUtils { * Get the fully qualified class names of all meta-annotation * types present on the annotation (of the specified * {@code annotationName}) on the supplied {@link AnnotatedElement}. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type on which to find meta-annotations; never {@code null} or empty @@ -137,7 +133,7 @@ public class AnnotatedElementUtils { */ public static Set getMetaAnnotationTypes(AnnotatedElement element, String annotationName) { Assert.notNull(element, "AnnotatedElement must not be null"); - Assert.hasText(annotationName, "annotationName must not be null or empty"); + Assert.hasLength(annotationName, "annotationName must not be null or empty"); final Set types = new LinkedHashSet(); @@ -159,17 +155,15 @@ public class AnnotatedElementUtils { throw new IllegalStateException("Failed to introspect annotations on " + element, ex); } - return (types.isEmpty() ? null : types); + return (!types.isEmpty() ? types : null); } /** * Determine if the supplied {@link AnnotatedElement} is annotated with * a composed annotation that is meta-annotated with an * annotation of the specified {@code annotationName}. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the meta-annotation * type to find; never {@code null} or empty @@ -178,13 +172,13 @@ public class AnnotatedElementUtils { */ public static boolean hasMetaAnnotationTypes(AnnotatedElement element, final String annotationName) { Assert.notNull(element, "AnnotatedElement must not be null"); - Assert.hasText(annotationName, "annotationName must not be null or empty"); + Assert.hasLength(annotationName, "annotationName must not be null or empty"); return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor() { @Override public Boolean process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { boolean found = annotation.annotationType().getName().equals(annotationName); - return ((found && (metaDepth > 0)) ? Boolean.TRUE : CONTINUE); + return (found && metaDepth > 0 ? Boolean.TRUE : CONTINUE); } })); } @@ -193,10 +187,8 @@ public class AnnotatedElementUtils { * Determine if an annotation of the specified {@code annotationName} * is present on the supplied {@link AnnotatedElement} or * within the annotation hierarchy above the specified element. - * *

If this method returns {@code true}, then {@link #getMergedAnnotationAttributes} * will return a non-null value. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. * @@ -207,7 +199,7 @@ public class AnnotatedElementUtils { */ public static boolean isAnnotated(AnnotatedElement element, final String annotationName) { Assert.notNull(element, "AnnotatedElement must not be null"); - Assert.hasText(annotationName, "annotationName must not be null or empty"); + Assert.hasLength(annotationName, "annotationName must not be null or empty"); return Boolean.TRUE.equals(searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor() { @Override @@ -224,13 +216,10 @@ public class AnnotatedElementUtils { * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy, and synthesize * the result back into an annotation of the specified {@code annotationType}. - * *

{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, Class)} * and {@link AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)}. - * * @param element the annotated element; never {@code null} * @param annotationType the annotation type to find; never {@code null} * @return the merged, synthesized {@code Annotation}, or {@code null} if not found @@ -249,12 +238,9 @@ public class AnnotatedElementUtils { * the annotation hierarchy above the supplied {@code element} and * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy. - * *

{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, String)}. - * * @param element the annotated element; never {@code null} * @param annotationType the annotation type to find; never {@code null} * @return the merged {@code AnnotationAttributes}, or {@code null} if not found @@ -282,13 +268,10 @@ public class AnnotatedElementUtils { * the annotation hierarchy above the supplied {@code element} and * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy. - * *

{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

This method delegates to {@link #getMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean)}, * supplying {@code false} for {@code classValuesAsString} and {@code nestedAnnotationsAsMap}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -310,6 +293,7 @@ public class AnnotatedElementUtils { @Deprecated public static AnnotationAttributes getAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { + return getMergedAnnotationAttributes(element, annotationName, classValuesAsString, nestedAnnotationsAsMap); } @@ -318,21 +302,17 @@ public class AnnotatedElementUtils { * the annotation hierarchy above the supplied {@code element} and * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy. - * *

Attributes from lower levels in the annotation hierarchy override * attributes of the same name from higher levels, and * {@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

In contrast to {@link #getAllAnnotationAttributes}, the search * algorithm used by this method will stop searching the annotation * hierarchy once the first annotation of the specified * {@code annotationName} has been found. As a consequence, additional * annotations of the specified {@code annotationName} will be ignored. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -352,9 +332,8 @@ public class AnnotatedElementUtils { boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = searchWithGetSemantics(element, annotationName, - new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap)); - AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, - nestedAnnotationsAsMap); + new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap)); + AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; } @@ -364,12 +343,9 @@ public class AnnotatedElementUtils { * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy, and synthesize * the result back into an annotation of the specified {@code annotationType}. - * *

{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

This method delegates to {@link #findMergedAnnotation(AnnotatedElement, String)}. - * * @param element the annotated element; never {@code null} * @param annotationType the annotation type to find; never {@code null} * @return the merged, synthesized {@code Annotation}, or {@code null} if not found @@ -389,14 +365,11 @@ public class AnnotatedElementUtils { * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy, and synthesize * the result back into an annotation of the specified {@code annotationName}. - * *

{@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

This method delegates to {@link #findMergedAnnotationAttributes(AnnotatedElement, String, boolean, boolean)} * (supplying {@code false} for {@code classValuesAsString} and {@code nestedAnnotationsAsMap}) * and {@link AnnotationUtils#synthesizeAnnotation(Map, Class, AnnotatedElement)}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -409,8 +382,8 @@ public class AnnotatedElementUtils { @SuppressWarnings("unchecked") public static A findMergedAnnotation(AnnotatedElement element, String annotationName) { AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationName, false, false); - return ((attributes != null) ? AnnotationUtils.synthesizeAnnotation(attributes, - (Class) attributes.annotationType(), element) : null); + return (attributes != null ? + AnnotationUtils.synthesizeAnnotation(attributes, (Class) attributes.annotationType(), element) : null); } /** @@ -418,21 +391,17 @@ public class AnnotatedElementUtils { * the annotation hierarchy above the supplied {@code element} and * merge that annotation's attributes with matching attributes from * annotations in lower levels of the annotation hierarchy. - * *

Attributes from lower levels in the annotation hierarchy override * attributes of the same name from higher levels, and * {@link AliasFor @AliasFor} semantics are fully supported, both * within a single annotation and within the annotation hierarchy. - * *

In contrast to {@link #getAllAnnotationAttributes}, the search * algorithm used by this method will stop searching the annotation * hierarchy once the first annotation of the specified * {@code annotationName} has been found. As a consequence, additional * annotations of the specified {@code annotationName} will be ignored. - * *

This method follows find semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -451,9 +420,8 @@ public class AnnotatedElementUtils { boolean classValuesAsString, boolean nestedAnnotationsAsMap) { AnnotationAttributes attributes = searchWithFindSemantics(element, annotationName, - new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap)); - AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, - nestedAnnotationsAsMap); + new MergedAnnotationAttributesProcessor(annotationName, classValuesAsString, nestedAnnotationsAsMap)); + AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); return attributes; } @@ -462,13 +430,10 @@ public class AnnotatedElementUtils { * the specified {@code annotationName} in the annotation hierarchy above * the supplied {@link AnnotatedElement} and store the results in a * {@link MultiValueMap}. - * *

Note: in contrast to {@link #getMergedAnnotationAttributes(AnnotatedElement, String)}, * this method does not support attribute overrides. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -486,13 +451,10 @@ public class AnnotatedElementUtils { * the specified {@code annotationName} in the annotation hierarchy above * the supplied {@link AnnotatedElement} and store the results in a * {@link MultiValueMap}. - * *

Note: in contrast to {@link #getMergedAnnotationAttributes(AnnotatedElement, String)}, * this method does not support attribute overrides. - * *

This method follows get semantics as described in the * {@linkplain AnnotatedElementUtils class-level Javadoc}. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -511,7 +473,6 @@ public class AnnotatedElementUtils { final MultiValueMap attributesMap = new LinkedMultiValueMap(); searchWithGetSemantics(element, annotationName, new SimpleAnnotationProcessor() { - @Override public Void process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { boolean found = annotation.annotationType().getName().equals(annotationName); @@ -522,19 +483,17 @@ public class AnnotatedElementUtils { attributesMap.add(entry.getKey(), entry.getValue()); } } - // Continue searching... return null; } }); - return (attributesMap.isEmpty() ? null : attributesMap); + return (!attributesMap.isEmpty() ? attributesMap : null); } /** * Search for annotations of the specified {@code annotationName} on * the specified {@code element}, following get semantics. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -555,11 +514,8 @@ public class AnnotatedElementUtils { * Perform the search algorithm for the {@link #searchWithGetSemantics} * method, avoiding endless recursion by tracking which annotated elements * have already been visited. - * *

The {@code metaDepth} parameter is explained in the - * {@link Processor#process process()} method of the {@link Processor} - * API. - * + * {@link Processor#process process()} method of the {@link Processor} API. * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -572,11 +528,10 @@ public class AnnotatedElementUtils { Processor processor, Set visited, int metaDepth) { Assert.notNull(element, "AnnotatedElement must not be null"); - Assert.hasText(annotationName, "annotationName must not be null or empty"); + Assert.hasLength(annotationName, "annotationName must not be null or empty"); if (visited.add(element)) { try { - // Start searching within locally declared annotations List declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations()); T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations, annotationName, processor, @@ -593,8 +548,8 @@ public class AnnotatedElementUtils { } // Continue searching within inherited annotations - result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations, annotationName, processor, - visited, metaDepth); + result = searchWithGetSemanticsInAnnotations( + element, inheritedAnnotations, annotationName, processor, visited, metaDepth); if (result != null) { return result; } @@ -611,15 +566,11 @@ public class AnnotatedElementUtils { * This method is invoked by * {@link #searchWithGetSemantics(AnnotatedElement, String, Processor, Set, int)} * to perform the actual search within the supplied list of annotations. - * *

This method should be invoked first with locally declared annotations * and then subsequently with inherited annotations, thereby allowing * local annotations to take precedence over inherited annotations. - * *

The {@code metaDepth} parameter is explained in the - * {@link Processor#process process()} method of the {@link Processor} - * API. - * + * {@link Processor#process process()} method of the {@link Processor} API. * @param annotatedElement the element that is annotated with the supplied * annotations, used for contextual logging; may be {@code null} if unknown * @param annotations the annotations to search in; never {@code null} @@ -636,8 +587,8 @@ public class AnnotatedElementUtils { // Search in annotations for (Annotation annotation : annotations) { - if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) - && (annotation.annotationType().getName().equals(annotationName) || metaDepth > 0)) { + if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation) && + (annotation.annotationType().getName().equals(annotationName) || metaDepth > 0)) { T result = processor.process(annotatedElement, annotation, metaDepth); if (result != null) { return result; @@ -648,8 +599,8 @@ public class AnnotatedElementUtils { // Recursively search in meta-annotations for (Annotation annotation : annotations) { if (!AnnotationUtils.isInJavaLangAnnotationPackage(annotation)) { - T result = searchWithGetSemantics(annotation.annotationType(), annotationName, processor, visited, - metaDepth + 1); + T result = searchWithGetSemantics( + annotation.annotationType(), annotationName, processor, visited, metaDepth + 1); if (result != null) { processor.postProcess(annotatedElement, annotation, result); return result; @@ -663,7 +614,6 @@ public class AnnotatedElementUtils { /** * Search for annotations of the specified {@code annotationName} on * the specified {@code element}, following find semantics. - * * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -685,11 +635,8 @@ public class AnnotatedElementUtils { * Perform the search algorithm for the {@link #searchWithFindSemantics} * method, avoiding endless recursion by tracking which annotated elements * have already been visited. - * *

The {@code metaDepth} parameter is explained in the - * {@link Processor#process process()} method of the {@link Processor} - * API. - * + * {@link Processor#process process()} method of the {@link Processor} API. * @param element the annotated element; never {@code null} * @param annotationName the fully qualified class name of the annotation * type to find; never {@code null} or empty @@ -703,7 +650,7 @@ public class AnnotatedElementUtils { Processor processor, Set visited, int metaDepth) { Assert.notNull(element, "AnnotatedElement must not be null"); - Assert.hasText(annotationName, "annotationName must not be null or empty"); + Assert.hasLength(annotationName, "annotationName must not be null or empty"); if (visited.add(element)) { try { @@ -759,11 +706,10 @@ public class AnnotatedElementUtils { } try { - Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), - method.getParameterTypes()); + Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes()); Method resolvedEquivalentMethod = BridgeMethodResolver.findBridgedMethod(equivalentMethod); - result = searchWithFindSemantics(resolvedEquivalentMethod, annotationName, processor, - visited, metaDepth); + result = searchWithFindSemantics( + resolvedEquivalentMethod, annotationName, processor, visited, metaDepth); if (result != null) { return result; } @@ -809,9 +755,6 @@ public class AnnotatedElementUtils { return null; } - /** - * @since 4.2 - */ private static T searchOnInterfaces(Method method, String annotationName, Processor processor, Set visited, int metaDepth, Class[] ifcs) { @@ -833,9 +776,9 @@ public class AnnotatedElementUtils { return null; } + /** * Callback interface that is used to process annotations during a search. - * *

Depending on the use case, a processor may choose to * {@linkplain #process} a single target annotation, multiple target * annotations, or all annotations discovered by the currently executing @@ -846,21 +789,18 @@ public class AnnotatedElementUtils { * whereas, returning {@code null} from the {@link #process} method * instructs the search algorithm to continue searching for additional * annotations. - * *

Processors can optionally {@linkplain #postProcess post-process} * the result of the {@link #process} method as the search algorithm * goes back down the annotation hierarchy from an invocation of * {@link #process} that returned a non-null value down to the * {@link AnnotatedElement} that was supplied as the starting point to * the search algorithm. - * * @param the type of result returned by the processor */ - private static interface Processor { + private interface Processor { /** * Process the supplied annotation. - * *

Depending on the use case, the supplied annotation may be an * actual target annotation that has been found by the search * algorithm, or it may be some other annotation within the @@ -868,14 +808,12 @@ public class AnnotatedElementUtils { * should have a value greater than {@code 0}. In any case, it is * up to concrete implementations of this method to decide what to * do with the supplied annotation. - * *

The {@code metaDepth} parameter represents the depth of the * annotation relative to the first annotated element in the * annotation hierarchy. For example, an annotation that is * present on a non-annotation element will have a depth * of 0; a meta-annotation will have a depth of 1; and a * meta-meta-annotation will have a depth of 2; etc. - * * @param annotatedElement the element that is annotated with the * supplied annotation, used for contextual logging; may be * {@code null} if unknown @@ -888,12 +826,10 @@ public class AnnotatedElementUtils { /** * Post-process the result returned by the {@link #process} method. - * *

The {@code annotation} supplied to this method is an annotation * that is present in the annotation hierarchy, between the initial * {@link AnnotatedElement} and an invocation of {@link #process} * that returned a non-null value. - * * @param annotatedElement the element that is annotated with the * supplied annotation, used for contextual logging; may be * {@code null} if unknown @@ -903,6 +839,7 @@ public class AnnotatedElementUtils { void postProcess(AnnotatedElement annotatedElement, Annotation annotation, T result); } + /** * {@link Processor} that {@linkplain #process processes} annotations * but does not {@linkplain #postProcess post-process} results. @@ -910,15 +847,13 @@ public class AnnotatedElementUtils { */ private abstract static class SimpleAnnotationProcessor implements Processor { - /** - * No-op. - */ @Override public final void postProcess(AnnotatedElement annotatedElement, Annotation annotation, T result) { - /* no-op */ + // no-op } } + /** * {@link Processor} that gets the {@code AnnotationAttributes} for the * target annotation during the {@link #process} phase and then merges @@ -931,12 +866,14 @@ public class AnnotatedElementUtils { private static class MergedAnnotationAttributesProcessor implements Processor { private final String annotationName; + private final boolean classValuesAsString; - private final boolean nestedAnnotationsAsMap; + private final boolean nestedAnnotationsAsMap; MergedAnnotationAttributesProcessor(String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { + this.annotationName = annotationName; this.classValuesAsString = classValuesAsString; this.nestedAnnotationsAsMap = nestedAnnotationsAsMap; @@ -946,7 +883,7 @@ public class AnnotatedElementUtils { public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { boolean found = annotation.annotationType().getName().equals(this.annotationName); return (found ? AnnotationUtils.getAnnotationAttributes(annotatedElement, annotation, - this.classValuesAsString, this.nestedAnnotationsAsMap, true) : null); + this.classValuesAsString, this.nestedAnnotationsAsMap, true) : null); } @Override @@ -975,11 +912,10 @@ public class AnnotatedElementUtils { AnnotationAttributes attributes, String sourceAttributeName, String targetAttributeName) { Object value = AnnotationUtils.getValue(annotation, sourceAttributeName); - Object adaptedValue = AnnotationUtils.adaptValue(element, value, this.classValuesAsString, - this.nestedAnnotationsAsMap); + Object adaptedValue = AnnotationUtils.adaptValue( + element, value, this.classValuesAsString, this.nestedAnnotationsAsMap); attributes.put(targetAttributeName, adaptedValue); } - } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java index 018c562bba..18d96b0771 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/ResponseBodyEmitter.java @@ -26,21 +26,22 @@ import org.springframework.util.Assert; /** * A controller method return value type for asynchronous request processing - * where one or more objects are written to the response. While - * {@link org.springframework.web.context.request.async.DeferredResult DeferredResult} + * where one or more objects are written to the response. + * + *

While {@link org.springframework.web.context.request.async.DeferredResult} * is used to produce a single result, a {@code ResponseBodyEmitter} can be used * to send multiple objects where each object is written with a compatible - * {@link org.springframework.http.converter.HttpMessageConverter HttpMessageConverter}. + * {@link org.springframework.http.converter.HttpMessageConverter}. * *

Supported as a return type on its own as well as within a - * {@link org.springframework.http.ResponseEntity ResponseEntity}. + * {@link org.springframework.http.ResponseEntity}. * *

  * @RequestMapping(value="/stream", method=RequestMethod.GET)
  * public ResponseBodyEmitter handle() {
- * 	ResponseBodyEmitter emitter = new ResponseBodyEmitter();
- * 	// Pass the emitter to another component...
- * 	return emitter;
+ * 	   ResponseBodyEmitter emitter = new ResponseBodyEmitter();
+ * 	   // Pass the emitter to another component...
+ * 	   return emitter;
  * }
  *
  * // in another thread
@@ -101,15 +102,6 @@ public class ResponseBodyEmitter {
 	}
 
 
-	/**
-	 * Invoked after the response is updated with the status code and headers,
-	 * if the ResponseBodyEmitter is wrapped in a ResponseEntity, but before the
-	 * response is committed, i.e. before the response body has been written to.
-	 * 

The default implementation is empty. - */ - protected void extendResponse(ServerHttpResponse outputMessage) { - } - synchronized void initialize(Handler handler) throws IOException { this.handler = handler; @@ -132,6 +124,15 @@ public class ResponseBodyEmitter { } } + /** + * Invoked after the response is updated with the status code and headers, + * if the ResponseBodyEmitter is wrapped in a ResponseEntity, but before the + * response is committed, i.e. before the response body has been written to. + *

The default implementation is empty. + */ + protected void extendResponse(ServerHttpResponse outputMessage) { + } + /** * Write the given object to the response. *

If any exception occurs a dispatch is made back to the app server where @@ -264,11 +265,11 @@ public class ResponseBodyEmitter { } } + private class DefaultCallback implements Runnable { private Runnable delegate; - public void setDelegate(Runnable delegate) { this.delegate = delegate; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java index 48d382b352..4bc3267e4e 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/SseEmitter.java @@ -169,9 +169,9 @@ public class SseEmitter extends ResponseBodyEmitter { /** * Return one or more Object-MediaType pairs to write via * {@link #send(Object, MediaType)}. + * @since 4.2.3 */ Set build(); - } -- GitLab