From 77a62ec8b8db6dde54d8e4d85e51048908caa54f Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 20 Oct 2014 17:42:18 +0200 Subject: [PATCH] Polishing --- .../beans/BeanInstantiationException.java | 5 +- .../jmx/export/MBeanExporter.java | 2 +- .../test/util/MetaAnnotationUtils.java | 143 +++++++----------- .../ServletServerContainerFactoryBean.java | 25 +-- 4 files changed, 73 insertions(+), 102 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java index 8b7b521724..c4b7ff45f4 100644 --- a/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java +++ b/spring-beans/src/main/java/org/springframework/beans/BeanInstantiationException.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * Copyright 2002-2014 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. @@ -49,11 +49,12 @@ public class BeanInstantiationException extends FatalBeanException { this.beanClass = beanClass; } + /** * Return the offending bean class. */ public Class getBeanClass() { - return beanClass; + return this.beanClass; } } diff --git a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java index 7b613903ac..4b357c5069 100644 --- a/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java +++ b/spring-context/src/main/java/org/springframework/jmx/export/MBeanExporter.java @@ -410,7 +410,7 @@ public class MBeanExporter extends MBeanRegistrationSupport implements MBeanExpo } /** - * Kick off bean registration automatically when deployed in an {@code ApplicationContext}. + * Kick off bean registration automatically after the regular singleton instantiation phase. * @see #registerBeans() */ @Override diff --git a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java index 6f55690981..b5846a29da 100644 --- a/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java +++ b/spring-test/src/main/java/org/springframework/test/util/MetaAnnotationUtils.java @@ -45,8 +45,8 @@ import org.springframework.util.ObjectUtils; * {@link org.springframework.test.context.TestExecutionListeners @TestExecutionListeners}, * and {@link org.springframework.test.context.ActiveProfiles @ActiveProfiles} * which offer support for merging and overriding various inherited - * annotation attributes (e.g., {@link - * org.springframework.test.context.ContextConfiguration#inheritLocations}). + * annotation attributes (e.g. + * {@link org.springframework.test.context.ContextConfiguration#inheritLocations}). * * @author Sam Brannen * @since 4.0 @@ -55,35 +55,26 @@ import org.springframework.util.ObjectUtils; */ public abstract class MetaAnnotationUtils { - private MetaAnnotationUtils() { - /* no-op */ - } - /** * Find the {@link AnnotationDescriptor} for the supplied {@code annotationType} * on the supplied {@link Class}, traversing its annotations and superclasses * if no annotation can be found on the given class itself. - * *

This method explicitly handles class-level annotations which are not * declared as {@linkplain java.lang.annotation.Inherited inherited} as * well as meta-annotations. - * *

The algorithm operates as follows: *

    - *
  1. Search for the annotation on the given class and return a corresponding - * {@code AnnotationDescriptor} if found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through the superclass hierarchy of the given class. + *
  4. Search for the annotation on the given class and return a corresponding + * {@code AnnotationDescriptor} if found. + *
  5. Recursively search through all annotations that the given class declares. + *
  6. Recursively search through the superclass hierarchy of the given class. *
- * *

In this context, the term recursively means that the search * process continues by returning to step #1 with the current annotation or * superclass as the class to look for annotations on. - * *

If the supplied {@code clazz} is an interface, only the interface * itself will be checked; the inheritance hierarchy for interfaces will not * be traversed. - * * @param clazz the class to look for annotations on * @param annotationType the type of annotation to look for * @return the corresponding annotation descriptor if the annotation was found; @@ -91,8 +82,9 @@ public abstract class MetaAnnotationUtils { * @see AnnotationUtils#findAnnotationDeclaringClass(Class, Class) * @see #findAnnotationDescriptorForTypes(Class, Class...) */ - public static AnnotationDescriptor findAnnotationDescriptor(Class clazz, - Class annotationType) { + public static AnnotationDescriptor findAnnotationDescriptor( + Class clazz, Class annotationType) { + return findAnnotationDescriptor(clazz, new HashSet(), annotationType); } @@ -100,7 +92,6 @@ public abstract class MetaAnnotationUtils { * Perform the search algorithm for {@link #findAnnotationDescriptor(Class, Class)}, * avoiding endless recursion by tracking which annotations have already been * visited. - * * @param clazz the class to look for annotations on * @param visited the set of annotations that have already been visited * @param annotationType the type of annotation to look for @@ -142,31 +133,25 @@ public abstract class MetaAnnotationUtils { * in the inheritance hierarchy of the specified {@code clazz} (including * the specified {@code clazz} itself) which declares at least one of the * specified {@code annotationTypes}. - * *

This method traverses the annotations and superclasses of the specified * {@code clazz} if no annotation can be found on the given class itself. - * *

This method explicitly handles class-level annotations which are not * declared as {@linkplain java.lang.annotation.Inherited inherited} as * well as meta-annotations. - * *

The algorithm operates as follows: *

    - *
  1. Search for a local declaration of one of the annotation types on - * the given class and return a corresponding {@code UntypedAnnotationDescriptor} - * if found. - *
  2. Recursively search through all annotations that the given class declares. - *
  3. Recursively search through the superclass hierarchy of the given class. + *
  4. Search for a local declaration of one of the annotation types on + * the given class and return a corresponding {@code UntypedAnnotationDescriptor} + * if found. + *
  5. Recursively search through all annotations that the given class declares. + *
  6. Recursively search through the superclass hierarchy of the given class. *
- * *

In this context, the term recursively means that the search * process continues by returning to step #1 with the current annotation or * superclass as the class to look for annotations on. - * *

If the supplied {@code clazz} is an interface, only the interface * itself will be checked; the inheritance hierarchy for interfaces will not * be traversed. - * * @param clazz the class to look for annotations on * @param annotationTypes the types of annotations to look for * @return the corresponding annotation descriptor if one of the annotations @@ -175,8 +160,9 @@ public abstract class MetaAnnotationUtils { * @see #findAnnotationDescriptor(Class, Class) */ @SuppressWarnings("unchecked") - public static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes(Class clazz, - Class... annotationTypes) { + public static UntypedAnnotationDescriptor findAnnotationDescriptorForTypes( + Class clazz, Class... annotationTypes) { + return findAnnotationDescriptorForTypes(clazz, new HashSet(), annotationTypes); } @@ -184,7 +170,6 @@ public abstract class MetaAnnotationUtils { * Perform the search algorithm for {@link #findAnnotationDescriptorForTypes(Class, Class...)}, * avoiding endless recursion by tracking which annotations have already been * visited. - * * @param clazz the class to look for annotations on * @param visited the set of annotations that have already been visited * @param annotationTypes the types of annotations to look for @@ -196,7 +181,6 @@ public abstract class MetaAnnotationUtils { Set visited, Class... annotationTypes) { assertNonEmptyAnnotationTypeArray(annotationTypes, "The list of annotation types must not be empty"); - if (clazz == null || clazz.equals(Object.class)) { return null; } @@ -224,49 +208,50 @@ public abstract class MetaAnnotationUtils { return findAnnotationDescriptorForTypes(clazz.getSuperclass(), visited, annotationTypes); } + private static void assertNonEmptyAnnotationTypeArray(Class[] annotationTypes, String message) { + if (ObjectUtils.isEmpty(annotationTypes)) { + throw new IllegalArgumentException(message); + } + for (Class clazz : annotationTypes) { + if (!Annotation.class.isAssignableFrom(clazz)) { + throw new IllegalArgumentException("Array elements must be of type Annotation"); + } + } + } + /** * Descriptor for an {@link Annotation}, including the {@linkplain * #getDeclaringClass() class} on which the annotation is declared * as well as the actual {@linkplain #getAnnotation() annotation} instance. - * - *

- * If the annotation is used as a meta-annotation, the descriptor also includes + *

If the annotation is used as a meta-annotation, the descriptor also includes * the {@linkplain #getComposedAnnotation() composed annotation} on which the * annotation is present. In such cases, the root declaring class is * not directly annotated with the annotation but rather indirectly via the * composed annotation. - * - *

- * Given the following example, if we are searching for the {@code @Transactional} + *

Given the following example, if we are searching for the {@code @Transactional} * annotation on the {@code TransactionalTests} class, then the * properties of the {@code AnnotationDescriptor} would be as follows. - * *

- * *
 	 * @Transactional
 	 * @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
 	 * public class TransactionalTests { }
 	 * 
- * - *

- * Given the following example, if we are searching for the {@code @Transactional} + *

Given the following example, if we are searching for the {@code @Transactional} * annotation on the {@code UserRepositoryTests} class, then the * properties of the {@code AnnotationDescriptor} would be as follows. - * *

- * *
 	 * @Transactional
 	 * @ContextConfiguration({"/test-datasource.xml", "/repository-config.xml"})
@@ -276,18 +261,18 @@ public abstract class MetaAnnotationUtils {
 	 * @RepositoryTests
 	 * public class UserRepositoryTests { }
 	 * 
- * - * @author Sam Brannen - * @since 4.0 */ public static class AnnotationDescriptor { private final Class rootDeclaringClass; - private final Class declaringClass; - private final Annotation composedAnnotation; - private final T annotation; - private final AnnotationAttributes annotationAttributes; + private final Class declaringClass; + + private final Annotation composedAnnotation; + + private final T annotation; + + private final AnnotationAttributes annotationAttributes; public AnnotationDescriptor(Class rootDeclaringClass, T annotation) { this(rootDeclaringClass, rootDeclaringClass, null, annotation); @@ -297,13 +282,12 @@ public abstract class MetaAnnotationUtils { Annotation composedAnnotation, T annotation) { Assert.notNull(rootDeclaringClass, "rootDeclaringClass must not be null"); Assert.notNull(annotation, "annotation must not be null"); - this.rootDeclaringClass = rootDeclaringClass; this.declaringClass = declaringClass; this.composedAnnotation = composedAnnotation; this.annotation = annotation; - this.annotationAttributes = AnnotatedElementUtils.getAnnotationAttributes(rootDeclaringClass, - annotation.annotationType().getName()); + this.annotationAttributes = AnnotatedElementUtils.getAnnotationAttributes( + rootDeclaringClass, annotation.annotationType().getName()); } public Class getRootDeclaringClass() { @@ -331,7 +315,7 @@ public abstract class MetaAnnotationUtils { } public Class getComposedAnnotationType() { - return this.composedAnnotation == null ? null : this.composedAnnotation.annotationType(); + return (this.composedAnnotation != null ? this.composedAnnotation.annotationType() : null); } /** @@ -339,22 +323,20 @@ public abstract class MetaAnnotationUtils { */ @Override public String toString() { - return new ToStringCreator(this)// - .append("rootDeclaringClass", rootDeclaringClass)// - .append("declaringClass", declaringClass)// - .append("composedAnnotation", composedAnnotation)// - .append("annotation", annotation)// - .toString(); + return new ToStringCreator(this) + .append("rootDeclaringClass", this.rootDeclaringClass) + .append("declaringClass", this.declaringClass) + .append("composedAnnotation", this.composedAnnotation) + .append("annotation", this.annotation) + .toString(); } } + /** * Untyped extension of {@code AnnotationDescriptor} that is used * to describe the declaration of one of several candidate annotation types * where the actual annotation type cannot be predetermined. - * - * @author Sam Brannen - * @since 4.0 */ public static class UntypedAnnotationDescriptor extends AnnotationDescriptor { @@ -368,17 +350,4 @@ public abstract class MetaAnnotationUtils { } } - - private static void assertNonEmptyAnnotationTypeArray(Class[] annotationTypes, String message) { - if (ObjectUtils.isEmpty(annotationTypes)) { - throw new IllegalArgumentException(message); - } - - for (Class clazz : annotationTypes) { - if (!Annotation.class.isAssignableFrom(clazz)) { - throw new IllegalArgumentException("Array elements must be of type Annotation"); - } - } - } - } diff --git a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java index eb4580c94f..6460c96dec 100644 --- a/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java +++ b/spring-websocket/src/main/java/org/springframework/web/socket/server/standard/ServletServerContainerFactoryBean.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-2014 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. @@ -26,23 +26,24 @@ import org.springframework.util.Assert; import org.springframework.web.context.ServletContextAware; /** - * A FactoryBean for configuring {@link javax.websocket.server.ServerContainer}. Since - * there is only one {@code ServerContainer} instance accessible under a well-known - * {@code javax.servlet.ServletContext} attribute, simply declaring this FactoryBean and - * using its setters allows configuring the {@code ServerContainer} through Spring - * configuration. + * A {@link FactoryBean} for configuring {@link javax.websocket.server.ServerContainer}. + * Since there is usually only one {@code ServerContainer} instance accessible under a + * well-known {@code javax.servlet.ServletContext} attribute, simply declaring this + * FactoryBean and using its setters allows for configuring the {@code ServerContainer} + * through Spring configuration. * *

This is useful even if the {@code ServerContainer} is not injected into any other - * bean. For example, an application can configure a {@link org.springframework.web.socket.server.support.DefaultHandshakeHandler}, a - * {@link org.springframework.web.socket.sockjs.SockJsService}, or {@link ServerEndpointExporter}, - * and separately declare this FactoryBean in order to customize the properties of the - * (one and only) {@code ServerContainer} instance. + * bean within the Spring application context. For example, an application can configure + * a {@link org.springframework.web.socket.server.support.DefaultHandshakeHandler}, + * a {@link org.springframework.web.socket.sockjs.SockJsService}, or + * {@link ServerEndpointExporter}, and separately declare this FactoryBean in order + * to customize the properties of the (one and only) {@code ServerContainer} instance. * * @author Rossen Stoyanchev * @since 4.0 */ public class ServletServerContainerFactoryBean - implements FactoryBean, InitializingBean, ServletContextAware { + implements FactoryBean, ServletContextAware, InitializingBean { private Long asyncSendTimeout; @@ -120,7 +121,7 @@ public class ServletServerContainerFactoryBean @Override public Class getObjectType() { - return ServerContainer.class; + return (this.serverContainer != null ? this.serverContainer.getClass() : ServerContainer.class); } @Override