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 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 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 {@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 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 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 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 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 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}.
*
* 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
* @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.
- *