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:
*
- *
Normal object creation via the '{@code new}' operator: this is
- * taken care of by advising {@code initialization()} join points.
- *
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.
+ *
Normal object creation via the '{@code new}' operator: this is
+ * taken care of by advising {@code initialization()} join points.
+ *
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.
*
-
- *
- * 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+ 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