From f2eea9d911d13e2635da06e99e7cd110687913bf Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Tue, 29 Jul 2014 11:42:37 +0200 Subject: [PATCH] Polishing (cherry picked from commit 8f484d3) --- .../TestSourceSetDependenciesPlugin.groovy | 3 +- .../AbstractDependencyInjectionAspect.aj | 51 +++++---- ...nterfaceDrivenDependencyInjectionAspect.aj | 104 +++++++++--------- .../aspectj/AnnotationBeanConfigurerAspect.aj | 39 ++++--- .../core/convert/Property.java | 40 +++---- .../convert/support/MapToMapConverter.java | 13 ++- .../util/comparator/InstanceComparator.java | 19 ++-- .../metadata/GenericCallMetaDataProvider.java | 49 +++++---- .../AnnotationConfigContextLoaderUtils.java | 10 +- .../SimpleStreamingClientHttpRequest.java | 7 +- .../web/method/ControllerAdviceBean.java | 23 ++-- .../web/util/HierarchicalUriComponents.java | 2 +- .../condition/ProducesRequestCondition.java | 4 +- .../ExceptionHandlerExceptionResolver.java | 40 ++++--- 14 files changed, 202 insertions(+), 202 deletions(-) diff --git a/buildSrc/src/main/groovy/org/springframework/build/gradle/TestSourceSetDependenciesPlugin.groovy b/buildSrc/src/main/groovy/org/springframework/build/gradle/TestSourceSetDependenciesPlugin.groovy index 8d252ffb79..2423bb0242 100644 --- a/buildSrc/src/main/groovy/org/springframework/build/gradle/TestSourceSetDependenciesPlugin.groovy +++ b/buildSrc/src/main/groovy/org/springframework/build/gradle/TestSourceSetDependenciesPlugin.groovy @@ -40,8 +40,7 @@ class TestSourceSetDependenciesPlugin implements Plugin { } } - private void collectProjectDependencies(Set projectDependencies, - Project project) { + private void collectProjectDependencies(Set projectDependencies, Project project) { for (def configurationName in ["compile", "optional", "provided", "testCompile"]) { Configuration configuration = project.getConfigurations().findByName(configurationName) if (configuration) { diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj index 58bebb9176..73030d03d7 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj @@ -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. @@ -27,20 +27,26 @@ import org.aspectj.lang.annotation.control.CodeGenerationHint; * @since 2.5.2 */ public abstract aspect AbstractDependencyInjectionAspect { - /** - * Select construction join points for objects to inject dependencies - */ - public abstract pointcut beanConstruction(Object bean); + + private pointcut preConstructionCondition() : + leastSpecificSuperTypeConstruction() && preConstructionConfiguration(); + + private pointcut postConstructionCondition() : + mostSpecificSubTypeConstruction() && !preConstructionConfiguration(); /** - * Select deserialization join points for objects to inject dependencies + * Select least specific super type that is marked for DI + * (so that injection occurs only once with pre-construction injection). */ - public abstract pointcut beanDeserialization(Object bean); + public abstract pointcut leastSpecificSuperTypeConstruction(); /** - * Select join points in a configurable bean + * Select the most-specific initialization join point + * (most concrete class) for the initialization of an instance. */ - public abstract pointcut inConfigurableBean(); + @CodeGenerationHint(ifNameSuffix="6f1") + public pointcut mostSpecificSubTypeConstruction() : + if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass()); /** * Select join points in beans to be configured prior to construction? @@ -49,29 +55,20 @@ public abstract aspect AbstractDependencyInjectionAspect { public pointcut preConstructionConfiguration() : if (false); /** - * Select the most-specific initialization join point - * (most concrete class) for the initialization of an instance. + * Select construction join points for objects to inject dependencies. */ - @CodeGenerationHint(ifNameSuffix="6f1") - public pointcut mostSpecificSubTypeConstruction() : - if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass()); + public abstract pointcut beanConstruction(Object bean); /** - * Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection + * Select deserialization join points for objects to inject dependencies. */ - public abstract pointcut leastSpecificSuperTypeConstruction(); + public abstract pointcut beanDeserialization(Object bean); /** - * Configure the bean + * Select join points in a configurable bean. */ - public abstract void configureBean(Object bean); - - - private pointcut preConstructionCondition() : - leastSpecificSuperTypeConstruction() && preConstructionConfiguration(); + public abstract pointcut inConfigurableBean(); - private pointcut postConstructionCondition() : - mostSpecificSubTypeConstruction() && !preConstructionConfiguration(); /** * Pre-construction configuration. @@ -100,4 +97,10 @@ public abstract aspect AbstractDependencyInjectionAspect { configureBean(bean); } + + /** + * Configure the given bean. + */ + public abstract void configureBean(Object bean); + } diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj index 8270d6962d..a65be5f5bb 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj @@ -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. @@ -20,49 +20,48 @@ import java.io.ObjectStreamException; import java.io.Serializable; /** - * An aspect that injects dependency into any object whose type implements the {@link ConfigurableObject} interface. - *

- * This aspect supports injecting into domain objects when they are created for the first time as well as - * upon deserialization. Subaspects need to simply provide definition for the configureBean() method. This - * method may be implemented without relying on Spring container if so desired. - *

- *

- * There are two cases that needs to be handled: + * An aspect that injects dependency into any object whose type implements the + * {@link ConfigurableObject} interface. + * + *

This aspect supports injecting into domain objects when they are created + * for the first time as well as upon deserialization. Subaspects need to simply + * provide definition for the configureBean() method. This method may be + * implemented without relying on Spring container if so desired. + * + *

There are two cases that needs to be handled: *

    - *
  1. Normal object creation via the '{@code new}' operator: this is - * taken care of by advising {@code initialization()} join points.
  2. - *
  3. Object creation through deserialization: since no constructor is - * invoked during deserialization, the aspect needs to advise a method that a - * deserialization mechanism is going to invoke. Ideally, we should not - * require user classes to implement any specific method. This implies that - * we need to introduce the chosen method. We should also handle the cases - * where the chosen method is already implemented in classes (in which case, - * the user's implementation for that method should take precedence over the - * introduced implementation). There are a few choices for the chosen method: - *
      - *
    • readObject(ObjectOutputStream): Java requires that the method must be - * {@code private}

      . Since aspects cannot introduce a private member, - * while preserving its name, this option is ruled out.
    • - *
    • readResolve(): Java doesn't pose any restriction on an access specifier. - * Problem solved! There is one (minor) limitation of this approach in - * that if a user class already has this method, that method must be - * {@code public}. However, this shouldn't be a big burden, since - * use cases that need classes to implement readResolve() (custom enums, - * for example) are unlikely to be marked as @Configurable, and - * in any case asking to make that method {@code public} should not - * pose any undue burden.
    • - *
    - * The minor collaboration needed by user classes (i.e., that the - * implementation of {@code readResolve()}, if any, must be - * {@code public}) can be lifted as well if we were to use an - * experimental feature in AspectJ - the {@code hasmethod()} PCD.
  4. + *
  5. Normal object creation via the '{@code new}' operator: this is + * taken care of by advising {@code initialization()} join points.
  6. + *
  7. Object creation through deserialization: since no constructor is + * invoked during deserialization, the aspect needs to advise a method that a + * deserialization mechanism is going to invoke. Ideally, we should not + * require user classes to implement any specific method. This implies that + * we need to introduce the chosen method. We should also handle the cases + * where the chosen method is already implemented in classes (in which case, + * the user's implementation for that method should take precedence over the + * introduced implementation). There are a few choices for the chosen method: + *
      + *
    • readObject(ObjectOutputStream): Java requires that the method must be + * {@code private}

      . Since aspects cannot introduce a private member, + * while preserving its name, this option is ruled out.
    • + *
    • readResolve(): Java doesn't pose any restriction on an access specifier. + * Problem solved! There is one (minor) limitation of this approach in + * that if a user class already has this method, that method must be + * {@code public}. However, this shouldn't be a big burden, since + * use cases that need classes to implement readResolve() (custom enums, + * for example) are unlikely to be marked as @Configurable, and + * in any case asking to make that method {@code public} should not + * pose any undue burden.
    • + *
    + * The minor collaboration needed by user classes (i.e., that the implementation of + * {@code readResolve()}, if any, must be {@code public}) can be lifted as well if we + * were to use an experimental feature in AspectJ - the {@code hasmethod()} PCD.
  8. *
- - *

- * While having type implement the {@link ConfigurableObject} interface is certainly a valid choice, an alternative - * is to use a 'declare parents' statement another aspect (a subaspect of this aspect would be a logical choice) - * that declares the classes that need to be configured by supplying the {@link ConfigurableObject} interface. - *

+ * + *

While having type implement the {@link ConfigurableObject} interface is certainly + * a valid choice, an alternative is to use a 'declare parents' statement another aspect + * (a subaspect of this aspect would be a logical choice) that declares the classes that + * need to be configured by supplying the {@link ConfigurableObject} interface. * * @author Ramnivas Laddad * @since 2.5.2 @@ -72,35 +71,33 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends * Select initialization join point as object construction */ public pointcut beanConstruction(Object bean) : - initialization(ConfigurableObject+.new(..)) && this(bean); + initialization(ConfigurableObject+.new(..)) && this(bean); /** * Select deserialization join point made available through ITDs for ConfigurableDeserializationSupport */ public pointcut beanDeserialization(Object bean) : - execution(Object ConfigurableDeserializationSupport+.readResolve()) && - this(bean); + execution(Object ConfigurableDeserializationSupport+.readResolve()) && this(bean); public pointcut leastSpecificSuperTypeConstruction() : initialization(ConfigurableObject.new(..)); // Implementation to support re-injecting dependencies once an object is deserialized + /** * Declare any class implementing Serializable and ConfigurableObject as also implementing - * ConfigurableDeserializationSupport. This allows us to introduce the readResolve() + * ConfigurableDeserializationSupport. This allows us to introduce the {@code readResolve()} * method and select it with the beanDeserialization() pointcut. - * *

Here is an improved version that uses the hasmethod() pointcut and lifts * even the minor requirement on user classes: - * - *

declare parents: ConfigurableObject+ Serializable+
-	 *		            && !hasmethod(Object readResolve() throws ObjectStreamException)
-	 *		            implements ConfigurableDeserializationSupport;
+	 * 
+	 * declare parents: ConfigurableObject+ Serializable+
+	 * && !hasmethod(Object readResolve() throws ObjectStreamException)
+	 * implements ConfigurableDeserializationSupport;
 	 * 
*/ - declare parents: - ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport; + declare parents: ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport; /** * A marker interface to which the {@code readResolve()} is introduced. @@ -111,7 +108,6 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends /** * Introduce the {@code readResolve()} method so that we can advise its * execution to configure the object. - * *

Note if a method with the same signature already exists in a * {@code Serializable} class of ConfigurableObject type, * that implementation will take precedence (a good thing, since we are diff --git a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AnnotationBeanConfigurerAspect.aj b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AnnotationBeanConfigurerAspect.aj index eea0835bd0..81635ccd0e 100644 --- a/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AnnotationBeanConfigurerAspect.aj +++ b/spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AnnotationBeanConfigurerAspect.aj @@ -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. @@ -19,7 +19,7 @@ package org.springframework.beans.factory.aspectj; import java.io.Serializable; import org.aspectj.lang.annotation.control.CodeGenerationHint; -import org.springframework.beans.BeansException; + import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.DisposableBean; @@ -44,48 +44,47 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport; * @see org.springframework.beans.factory.annotation.Configurable * @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver */ -public aspect AnnotationBeanConfigurerAspect - extends AbstractInterfaceDrivenDependencyInjectionAspect +public aspect AnnotationBeanConfigurerAspect extends AbstractInterfaceDrivenDependencyInjectionAspect implements BeanFactoryAware, InitializingBean, DisposableBean { private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport(); - public pointcut inConfigurableBean() : @this(Configurable); - public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*); - - declare parents: @Configurable * implements ConfigurableObject; - - public void configureBean(Object bean) { - beanConfigurerSupport.configureBean(bean); + public void setBeanFactory(BeanFactory beanFactory) { + this.beanConfigurerSupport.setBeanFactory(beanFactory); + this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver()); } - - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - beanConfigurerSupport.setBeanFactory(beanFactory); - beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver()); + public void afterPropertiesSet() throws Exception { + this.beanConfigurerSupport.afterPropertiesSet(); } - public void afterPropertiesSet() throws Exception { - beanConfigurerSupport.afterPropertiesSet(); + public void configureBean(Object bean) { + this.beanConfigurerSupport.configureBean(bean); } public void destroy() throws Exception { - beanConfigurerSupport.destroy(); + this.beanConfigurerSupport.destroy(); } + public pointcut inConfigurableBean() : @this(Configurable); + + public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*); + /* * An intermediary to match preConstructionConfiguration signature (that doesn't expose the annotation object) */ @CodeGenerationHint(ifNameSuffix="bb0") private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if (c.preConstruction()); + + declare parents: @Configurable * implements ConfigurableObject; + /* * This declaration shouldn't be needed, * except for an AspectJ bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=214559) */ - declare parents: @Configurable Serializable+ - implements ConfigurableDeserializationSupport; + declare parents: @Configurable Serializable+ implements ConfigurableDeserializationSupport; } diff --git a/spring-core/src/main/java/org/springframework/core/convert/Property.java b/spring-core/src/main/java/org/springframework/core/convert/Property.java index bdab6cc987..84258e9d96 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/Property.java +++ b/spring-core/src/main/java/org/springframework/core/convert/Property.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. @@ -62,6 +62,7 @@ public final class Property { private Annotation[] annotations; + public Property(Class objectType, Method readMethod, Method writeMethod) { this(objectType, readMethod, writeMethod, null); } @@ -241,34 +242,25 @@ public final class Property { } } - @Override - public int hashCode() { - final int prime = 31; - int hashCode = 1; - hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.objectType); - hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.readMethod); - hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.writeMethod); - hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.name); - return hashCode; - } @Override - public boolean equals(Object obj) { - if (this == obj) { + public boolean equals(Object other) { + if (this == other) { return true; } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { + if (!(other instanceof Property)) { return false; } - Property other = (Property) obj; - boolean equals = true; - equals &= ObjectUtils.nullSafeEquals(this.objectType, other.objectType); - equals &= ObjectUtils.nullSafeEquals(this.readMethod, other.readMethod); - equals &= ObjectUtils.nullSafeEquals(this.writeMethod, other.writeMethod); - equals &= ObjectUtils.nullSafeEquals(this.name, other.name); - return equals; + Property otherProperty = (Property) other; + return (ObjectUtils.nullSafeEquals(this.objectType, otherProperty.objectType) && + ObjectUtils.nullSafeEquals(this.name, otherProperty.name) && + ObjectUtils.nullSafeEquals(this.readMethod, otherProperty.readMethod) && + ObjectUtils.nullSafeEquals(this.writeMethod, otherProperty.writeMethod)); } + + @Override + public int hashCode() { + return (ObjectUtils.nullSafeHashCode(this.objectType) * 31 + ObjectUtils.nullSafeHashCode(this.name)); + } + } diff --git a/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java b/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java index 1222815617..0a300b2588 100644 --- a/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.java +++ b/spring-core/src/main/java/org/springframework/core/convert/support/MapToMapConverter.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. @@ -42,10 +42,12 @@ final class MapToMapConverter implements ConditionalGenericConverter { private final ConversionService conversionService; + public MapToMapConverter(ConversionService conversionService) { this.conversionService = conversionService; } + @Override public Set getConvertibleTypes() { return Collections.singleton(new ConvertiblePair(Map.class, Map.class)); @@ -88,6 +90,7 @@ final class MapToMapConverter implements ConditionalGenericConverter { return targetMap; } + // internal helpers private boolean canConvertKey(TypeDescriptor sourceType, TypeDescriptor targetType) { @@ -114,10 +117,12 @@ final class MapToMapConverter implements ConditionalGenericConverter { return this.conversionService.convert(sourceValue, sourceType.getMapValueTypeDescriptor(sourceValue), targetType); } + private static class MapEntry { - private Object key; - private Object value; + private final Object key; + + private final Object value; public MapEntry(Object key, Object value) { this.key = key; @@ -125,7 +130,7 @@ final class MapToMapConverter implements ConditionalGenericConverter { } public void addToMap(Map map) { - map.put(key, value); + map.put(this.key, this.value); } } diff --git a/spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.java b/spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.java index 04c8edfa94..35d324ee25 100644 --- a/spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.java +++ b/spring-core/src/main/java/org/springframework/util/comparator/InstanceComparator.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. @@ -31,23 +31,22 @@ import org.springframework.util.Assert; * is required. * * @author Phillip Webb - * @param The type of objects being compared - * @see CompoundComparator * @since 3.2 + * @param the type of objects being compared + * @see CompoundComparator */ public class InstanceComparator implements Comparator { - private Class[] instanceOrder; + private final Class[] instanceOrder; /** * Create a new {@link InstanceComparator} instance. - * * @param instanceOrder the ordered list of classes that should be used when comparing * objects. Classes earlier in the list will be be given a higher priority. */ public InstanceComparator(Class... instanceOrder) { - Assert.notNull(instanceOrder, "InstanceOrder must not be null"); + Assert.notNull(instanceOrder, "'instanceOrder' must not be null"); this.instanceOrder = instanceOrder; } @@ -61,13 +60,13 @@ public class InstanceComparator implements Comparator { private int getOrder(T object) { if (object != null) { - for (int i = 0; i < instanceOrder.length; i++) { - if (instanceOrder[i].isInstance(object)) { + for (int i = 0; i < this.instanceOrder.length; i++) { + if (this.instanceOrder[i].isInstance(object)) { return i; } } } - return instanceOrder.length; + return this.instanceOrder.length; } -} \ No newline at end of file +} diff --git a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java index 49f93ae9c7..2f4821a7a7 100644 --- a/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.java +++ b/spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/GenericCallMetaDataProvider.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. @@ -73,26 +73,34 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { try { setSupportsCatalogsInProcedureCalls(databaseMetaData.supportsCatalogsInProcedureCalls()); } - catch (SQLException se) { - logger.warn("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + se.getMessage()); + catch (SQLException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.supportsCatalogsInProcedureCalls' - " + ex.getMessage()); + } } try { setSupportsSchemasInProcedureCalls(databaseMetaData.supportsSchemasInProcedureCalls()); } - catch (SQLException se) { - logger.warn("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + se.getMessage()); + catch (SQLException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.supportsSchemasInProcedureCalls' - " + ex.getMessage()); + } } try { setStoresUpperCaseIdentifiers(databaseMetaData.storesUpperCaseIdentifiers()); } - catch (SQLException se) { - logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + se.getMessage()); + catch (SQLException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.storesUpperCaseIdentifiers' - " + ex.getMessage()); + } } try { setStoresLowerCaseIdentifiers(databaseMetaData.storesLowerCaseIdentifiers()); } - catch (SQLException se) { - logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + se.getMessage()); + catch (SQLException ex) { + if (logger.isWarnEnabled()) { + logger.warn("Error retrieving 'DatabaseMetaData.storesLowerCaseIdentifiers' - " + ex.getMessage()); + } } } @@ -341,12 +349,8 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { columnType == DatabaseMetaData.procedureColumnInOut || columnType == DatabaseMetaData.procedureColumnOut)) { if (logger.isDebugEnabled()) { - logger.debug("Skipping metadata for: " - + columnName + - " " + columnType + - " " + procs.getInt("DATA_TYPE") + - " " + procs.getString("TYPE_NAME") + - " " + procs.getBoolean("NULLABLE") + + logger.debug("Skipping metadata for: " + columnType + " " + procs.getInt("DATA_TYPE") + + " " + procs.getString("TYPE_NAME") + " " + procs.getBoolean("NULLABLE") + " (probably a member of a collection)" ); } @@ -355,18 +359,19 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { CallParameterMetaData meta = new CallParameterMetaData(columnName, columnType, procs.getInt("DATA_TYPE"), procs.getString("TYPE_NAME"), procs.getBoolean("NULLABLE") ); - callParameterMetaData.add(meta); + this.callParameterMetaData.add(meta); if (logger.isDebugEnabled()) { logger.debug("Retrieved metadata: " + meta.getParameterName() + " " + - meta.getParameterType() + " " + meta.getSqlType() + - " " + meta.getTypeName() + " " + meta.isNullable() - ); + meta.getParameterType() + " " + meta.getSqlType() + " " + + meta.getTypeName() + " " + meta.isNullable()); } } } } catch (SQLException ex) { - logger.warn("Error while retrieving metadata for procedure columns: " + ex); + if (logger.isWarnEnabled()) { + logger.warn("Error while retrieving metadata for procedure columns: " + ex); + } } finally { try { @@ -375,7 +380,9 @@ public class GenericCallMetaDataProvider implements CallMetaDataProvider { } } catch (SQLException ex) { - logger.warn("Problem closing ResultSet for procedure column metadata: " + ex); + if (logger.isWarnEnabled()) { + logger.warn("Problem closing ResultSet for procedure column metadata: " + ex); + } } } } diff --git a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java index db38ef36d3..6125ffb31a 100644 --- a/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java +++ b/spring-test/src/main/java/org/springframework/test/context/support/AnnotationConfigContextLoaderUtils.java @@ -68,8 +68,8 @@ public abstract class AnnotationConfigContextLoaderUtils { else { if (logger.isDebugEnabled()) { logger.debug(String.format( - "Ignoring class [%s]; it must be static, non-private, non-final, and annotated " - + "with @Configuration to be considered a default configuration class.", + "Ignoring class [%s]; it must be static, non-private, non-final, and annotated " + + "with @Configuration to be considered a default configuration class.", candidate.getName())); } } @@ -77,9 +77,9 @@ public abstract class AnnotationConfigContextLoaderUtils { if (configClasses.isEmpty()) { if (logger.isInfoEnabled()) { - logger.info(String.format("Could not detect default configuration classes for test class [%s]: " - + "%s does not declare any static, non-private, non-final, inner classes " - + "annotated with @Configuration.", declaringClass.getName(), declaringClass.getSimpleName())); + logger.info(String.format("Could not detect default configuration classes for test class [%s]: " + + "%s does not declare any static, non-private, non-final, inner classes " + + "annotated with @Configuration.", declaringClass.getName(), declaringClass.getSimpleName())); } } diff --git a/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java b/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java index 58841e2278..4df9392cd3 100644 --- a/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/client/SimpleStreamingClientHttpRequest.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. @@ -47,14 +47,13 @@ final class SimpleStreamingClientHttpRequest extends AbstractClientHttpRequest { private final boolean outputStreaming; - SimpleStreamingClientHttpRequest(HttpURLConnection connection, int chunkSize, - boolean outputStreaming) { + SimpleStreamingClientHttpRequest(HttpURLConnection connection, int chunkSize, boolean outputStreaming) { this.connection = connection; this.chunkSize = chunkSize; this.outputStreaming = outputStreaming; } - @Override + public HttpMethod getMethod() { return HttpMethod.valueOf(this.connection.getRequestMethod()); } diff --git a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java index d762eb60fa..a707a88dfa 100644 --- a/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java +++ b/spring-web/src/main/java/org/springframework/web/method/ControllerAdviceBean.java @@ -72,8 +72,11 @@ public class ControllerAdviceBean implements Ordered { public ControllerAdviceBean(String beanName, BeanFactory beanFactory) { Assert.hasText(beanName, "Bean name must not be null"); Assert.notNull(beanFactory, "BeanFactory must not be null"); - Assert.isTrue(beanFactory.containsBean(beanName), - "BeanFactory [" + beanFactory + "] does not contain bean with name '" + beanName + "'"); + + if (!beanFactory.containsBean(beanName)) { + throw new IllegalArgumentException( + "BeanFactory [" + beanFactory + "] does not contain bean with name '" + beanName + "'"); + } this.bean = beanName; this.beanFactory = beanFactory; @@ -132,7 +135,7 @@ public class ControllerAdviceBean implements Ordered { * Return a bean instance if necessary resolving the bean name through the BeanFactory. */ public Object resolveBean() { - return (this.bean instanceof String) ? this.beanFactory.getBean((String) this.bean) : this.bean; + return (this.bean instanceof String ? this.beanFactory.getBean((String) this.bean) : this.bean); } /** @@ -173,20 +176,14 @@ public class ControllerAdviceBean implements Ordered { @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (o != null && o instanceof ControllerAdviceBean) { - ControllerAdviceBean other = (ControllerAdviceBean) o; - return this.bean.equals(other.bean); - } - return false; + public boolean equals(Object other) { + return (this == other || + (other instanceof ControllerAdviceBean && this.bean.equals(((ControllerAdviceBean) other).bean))); } @Override public int hashCode() { - return 31 * this.bean.hashCode(); + return this.bean.hashCode(); } @Override diff --git a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java index 4e9d4b1bdf..2239eee408 100644 --- a/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java +++ b/spring-web/src/main/java/org/springframework/web/util/HierarchicalUriComponents.java @@ -616,7 +616,7 @@ final class HierarchicalUriComponents extends UriComponents { @Override public String getPath() { - return path; + return this.path; } @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java index c51f16fbe7..bc99eae487 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java @@ -103,7 +103,7 @@ public final class ProducesRequestCondition extends AbstractRequestCondition customArgumentResolvers; + private HandlerMethodArgumentResolverComposite argumentResolvers; + private List customReturnValueHandlers; + private HandlerMethodReturnValueHandlerComposite returnValueHandlers; + private List> messageConverters; private ContentNegotiationManager contentNegotiationManager = new ContentNegotiationManager(); + private ApplicationContext applicationContext; + private final Map, ExceptionHandlerMethodResolver> exceptionHandlerCache = new ConcurrentHashMap, ExceptionHandlerMethodResolver>(64); private final Map exceptionHandlerAdviceCache = new LinkedHashMap(); - private HandlerMethodArgumentResolverComposite argumentResolvers; - - private HandlerMethodReturnValueHandlerComposite returnValueHandlers; - - private ApplicationContext applicationContext; - /** - * Default constructor. - */ public ExceptionHandlerExceptionResolver() { - StringHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter(); stringHttpMessageConverter.setWriteAcceptCharset(false); // See SPR-7316 @@ -106,6 +102,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce this.messageConverters.add(new AllEncompassingFormHttpMessageConverter()); } + /** * Provide resolvers for custom argument types. Custom resolvers are ordered * after built-in ones. To override the built-in support for argument @@ -194,7 +191,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce * Return the configured message body converters. */ public List> getMessageConverters() { - return messageConverters; + return this.messageConverters; } /** @@ -223,7 +220,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce } @Override - public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + public void setApplicationContext(ApplicationContext applicationContext) { this.applicationContext = applicationContext; } @@ -231,6 +228,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce return this.applicationContext; } + @Override public void afterPropertiesSet() { if (this.argumentResolvers == null) { @@ -315,6 +313,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce } } + /** * Find an {@code @ExceptionHandler} method and invoke it to handle the raised exception. */ @@ -340,7 +339,9 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce exceptionHandlerMethod.invokeAndHandle(webRequest, mavContainer, exception); } catch (Exception invocationEx) { - logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx); + if (logger.isErrorEnabled()) { + logger.error("Failed to invoke @ExceptionHandler method: " + exceptionHandlerMethod, invocationEx); + } return null; } @@ -363,12 +364,13 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce * and if not found, it continues searching for additional {@code @ExceptionHandler} * methods assuming some {@linkplain ControllerAdvice @ControllerAdvice} * Spring-managed beans were detected. - * @param handlerMethod the method where the exception was raised, possibly {@code null} + * @param handlerMethod the method where the exception was raised (may be {@code null}) * @param exception the raised exception * @return a method to handle the exception, or {@code null} */ protected ServletInvocableHandlerMethod getExceptionHandlerMethod(HandlerMethod handlerMethod, Exception exception) { - Class handlerType = (handlerMethod != null) ? handlerMethod.getBeanType() : null; + Class handlerType = (handlerMethod != null ? handlerMethod.getBeanType() : null); + if (handlerMethod != null) { ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.get(handlerType); if (resolver == null) { @@ -380,6 +382,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method); } } + for (Entry entry : this.exceptionHandlerAdviceCache.entrySet()) { if (entry.getKey().isApplicableToBeanType(handlerType)) { ExceptionHandlerMethodResolver resolver = entry.getValue(); @@ -389,6 +392,7 @@ public class ExceptionHandlerExceptionResolver extends AbstractHandlerMethodExce } } } + return null; }