Skip to content

Commit 8f484d3

Browse files
committed
Polishing
1 parent 7bc9660 commit 8f484d3

File tree

14 files changed

+217
-221
lines changed

14 files changed

+217
-221
lines changed

buildSrc/src/main/groovy/org/springframework/build/gradle/TestSourceSetDependenciesPlugin.groovy

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,7 @@ class TestSourceSetDependenciesPlugin implements Plugin<Project> {
4040
}
4141
}
4242

43-
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies,
44-
Project project) {
43+
private void collectProjectDependencies(Set<ProjectDependency> projectDependencies, Project project) {
4544
for (def configurationName in ["compile", "optional", "provided", "testCompile"]) {
4645
Configuration configuration = project.getConfigurations().findByName(configurationName)
4746
if (configuration) {

spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractDependencyInjectionAspect.aj

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -27,20 +27,26 @@ import org.aspectj.lang.annotation.control.CodeGenerationHint;
2727
* @since 2.5.2
2828
*/
2929
public abstract aspect AbstractDependencyInjectionAspect {
30-
/**
31-
* Select construction join points for objects to inject dependencies
32-
*/
33-
public abstract pointcut beanConstruction(Object bean);
30+
31+
private pointcut preConstructionCondition() :
32+
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
33+
34+
private pointcut postConstructionCondition() :
35+
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
3436

3537
/**
36-
* Select deserialization join points for objects to inject dependencies
38+
* Select least specific super type that is marked for DI
39+
* (so that injection occurs only once with pre-construction injection).
3740
*/
38-
public abstract pointcut beanDeserialization(Object bean);
41+
public abstract pointcut leastSpecificSuperTypeConstruction();
3942

4043
/**
41-
* Select join points in a configurable bean
44+
* Select the most-specific initialization join point
45+
* (most concrete class) for the initialization of an instance.
4246
*/
43-
public abstract pointcut inConfigurableBean();
47+
@CodeGenerationHint(ifNameSuffix="6f1")
48+
public pointcut mostSpecificSubTypeConstruction() :
49+
if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
4450

4551
/**
4652
* Select join points in beans to be configured prior to construction?
@@ -49,29 +55,20 @@ public abstract aspect AbstractDependencyInjectionAspect {
4955
public pointcut preConstructionConfiguration() : if (false);
5056

5157
/**
52-
* Select the most-specific initialization join point
53-
* (most concrete class) for the initialization of an instance.
58+
* Select construction join points for objects to inject dependencies.
5459
*/
55-
@CodeGenerationHint(ifNameSuffix="6f1")
56-
public pointcut mostSpecificSubTypeConstruction() :
57-
if (thisJoinPoint.getSignature().getDeclaringType() == thisJoinPoint.getThis().getClass());
60+
public abstract pointcut beanConstruction(Object bean);
5861

5962
/**
60-
* Select least specific super type that is marked for DI (so that injection occurs only once with pre-construction inejection
63+
* Select deserialization join points for objects to inject dependencies.
6164
*/
62-
public abstract pointcut leastSpecificSuperTypeConstruction();
65+
public abstract pointcut beanDeserialization(Object bean);
6366

6467
/**
65-
* Configure the bean
68+
* Select join points in a configurable bean.
6669
*/
67-
public abstract void configureBean(Object bean);
68-
69-
70-
private pointcut preConstructionCondition() :
71-
leastSpecificSuperTypeConstruction() && preConstructionConfiguration();
70+
public abstract pointcut inConfigurableBean();
7271

73-
private pointcut postConstructionCondition() :
74-
mostSpecificSubTypeConstruction() && !preConstructionConfiguration();
7572

7673
/**
7774
* Pre-construction configuration.
@@ -100,4 +97,10 @@ public abstract aspect AbstractDependencyInjectionAspect {
10097
configureBean(bean);
10198
}
10299

100+
101+
/**
102+
* Configure the given bean.
103+
*/
104+
public abstract void configureBean(Object bean);
105+
103106
}

spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AbstractInterfaceDrivenDependencyInjectionAspect.aj

Lines changed: 50 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,49 +20,48 @@ import java.io.ObjectStreamException;
2020
import java.io.Serializable;
2121

2222
/**
23-
* An aspect that injects dependency into any object whose type implements the {@link ConfigurableObject} interface.
24-
* <p>
25-
* This aspect supports injecting into domain objects when they are created for the first time as well as
26-
* upon deserialization. Subaspects need to simply provide definition for the configureBean() method. This
27-
* method may be implemented without relying on Spring container if so desired.
28-
* </p>
29-
* <p>
30-
* There are two cases that needs to be handled:
23+
* An aspect that injects dependency into any object whose type implements the
24+
* {@link ConfigurableObject} interface.
25+
*
26+
* <p>This aspect supports injecting into domain objects when they are created
27+
* for the first time as well as upon deserialization. Subaspects need to simply
28+
* provide definition for the configureBean() method. This method may be
29+
* implemented without relying on Spring container if so desired.
30+
*
31+
* <p>There are two cases that needs to be handled:
3132
* <ol>
32-
* <li>Normal object creation via the '{@code new}' operator: this is
33-
* taken care of by advising {@code initialization()} join points.</li>
34-
* <li>Object creation through deserialization: since no constructor is
35-
* invoked during deserialization, the aspect needs to advise a method that a
36-
* deserialization mechanism is going to invoke. Ideally, we should not
37-
* require user classes to implement any specific method. This implies that
38-
* we need to <i>introduce</i> the chosen method. We should also handle the cases
39-
* where the chosen method is already implemented in classes (in which case,
40-
* the user's implementation for that method should take precedence over the
41-
* introduced implementation). There are a few choices for the chosen method:
42-
* <ul>
43-
* <li>readObject(ObjectOutputStream): Java requires that the method must be
44-
* {@code private}</p>. Since aspects cannot introduce a private member,
45-
* while preserving its name, this option is ruled out.</li>
46-
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
47-
* Problem solved! There is one (minor) limitation of this approach in
48-
* that if a user class already has this method, that method must be
49-
* {@code public}. However, this shouldn't be a big burden, since
50-
* use cases that need classes to implement readResolve() (custom enums,
51-
* for example) are unlikely to be marked as &#64;Configurable, and
52-
* in any case asking to make that method {@code public} should not
53-
* pose any undue burden.</li>
54-
* </ul>
55-
* The minor collaboration needed by user classes (i.e., that the
56-
* implementation of {@code readResolve()}, if any, must be
57-
* {@code public}) can be lifted as well if we were to use an
58-
* experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
33+
* <li>Normal object creation via the '{@code new}' operator: this is
34+
* taken care of by advising {@code initialization()} join points.</li>
35+
* <li>Object creation through deserialization: since no constructor is
36+
* invoked during deserialization, the aspect needs to advise a method that a
37+
* deserialization mechanism is going to invoke. Ideally, we should not
38+
* require user classes to implement any specific method. This implies that
39+
* we need to <i>introduce</i> the chosen method. We should also handle the cases
40+
* where the chosen method is already implemented in classes (in which case,
41+
* the user's implementation for that method should take precedence over the
42+
* introduced implementation). There are a few choices for the chosen method:
43+
* <ul>
44+
* <li>readObject(ObjectOutputStream): Java requires that the method must be
45+
* {@code private}</p>. Since aspects cannot introduce a private member,
46+
* while preserving its name, this option is ruled out.</li>
47+
* <li>readResolve(): Java doesn't pose any restriction on an access specifier.
48+
* Problem solved! There is one (minor) limitation of this approach in
49+
* that if a user class already has this method, that method must be
50+
* {@code public}. However, this shouldn't be a big burden, since
51+
* use cases that need classes to implement readResolve() (custom enums,
52+
* for example) are unlikely to be marked as &#64;Configurable, and
53+
* in any case asking to make that method {@code public} should not
54+
* pose any undue burden.</li>
55+
* </ul>
56+
* The minor collaboration needed by user classes (i.e., that the implementation of
57+
* {@code readResolve()}, if any, must be {@code public}) can be lifted as well if we
58+
* were to use an experimental feature in AspectJ - the {@code hasmethod()} PCD.</li>
5959
* </ol>
60-
61-
* <p>
62-
* While having type implement the {@link ConfigurableObject} interface is certainly a valid choice, an alternative
63-
* is to use a 'declare parents' statement another aspect (a subaspect of this aspect would be a logical choice)
64-
* that declares the classes that need to be configured by supplying the {@link ConfigurableObject} interface.
65-
* </p>
60+
*
61+
* <p>While having type implement the {@link ConfigurableObject} interface is certainly
62+
* a valid choice, an alternative is to use a 'declare parents' statement another aspect
63+
* (a subaspect of this aspect would be a logical choice) that declares the classes that
64+
* need to be configured by supplying the {@link ConfigurableObject} interface.
6665
*
6766
* @author Ramnivas Laddad
6867
* @since 2.5.2
@@ -72,35 +71,33 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
7271
* Select initialization join point as object construction
7372
*/
7473
public pointcut beanConstruction(Object bean) :
75-
initialization(ConfigurableObject+.new(..)) && this(bean);
74+
initialization(ConfigurableObject+.new(..)) && this(bean);
7675

7776
/**
7877
* Select deserialization join point made available through ITDs for ConfigurableDeserializationSupport
7978
*/
8079
public pointcut beanDeserialization(Object bean) :
81-
execution(Object ConfigurableDeserializationSupport+.readResolve()) &&
82-
this(bean);
80+
execution(Object ConfigurableDeserializationSupport+.readResolve()) && this(bean);
8381

8482
public pointcut leastSpecificSuperTypeConstruction() : initialization(ConfigurableObject.new(..));
8583

8684

8785

8886
// Implementation to support re-injecting dependencies once an object is deserialized
87+
8988
/**
9089
* Declare any class implementing Serializable and ConfigurableObject as also implementing
91-
* ConfigurableDeserializationSupport. This allows us to introduce the readResolve()
90+
* ConfigurableDeserializationSupport. This allows us to introduce the {@code readResolve()}
9291
* method and select it with the beanDeserialization() pointcut.
93-
*
9492
* <p>Here is an improved version that uses the hasmethod() pointcut and lifts
9593
* even the minor requirement on user classes:
96-
*
97-
* <pre class="code">declare parents: ConfigurableObject+ Serializable+
98-
* && !hasmethod(Object readResolve() throws ObjectStreamException)
99-
* implements ConfigurableDeserializationSupport;
94+
* <pre class="code">
95+
* declare parents: ConfigurableObject+ Serializable+
96+
* && !hasmethod(Object readResolve() throws ObjectStreamException)
97+
* implements ConfigurableDeserializationSupport;
10098
* </pre>
10199
*/
102-
declare parents:
103-
ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
100+
declare parents: ConfigurableObject+ && Serializable+ implements ConfigurableDeserializationSupport;
104101

105102
/**
106103
* A marker interface to which the {@code readResolve()} is introduced.
@@ -111,7 +108,6 @@ public abstract aspect AbstractInterfaceDrivenDependencyInjectionAspect extends
111108
/**
112109
* Introduce the {@code readResolve()} method so that we can advise its
113110
* execution to configure the object.
114-
*
115111
* <p>Note if a method with the same signature already exists in a
116112
* {@code Serializable} class of ConfigurableObject type,
117113
* that implementation will take precedence (a good thing, since we are

spring-aspects/src/main/java/org/springframework/beans/factory/aspectj/AnnotationBeanConfigurerAspect.aj

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2013 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -19,7 +19,7 @@ package org.springframework.beans.factory.aspectj;
1919
import java.io.Serializable;
2020

2121
import org.aspectj.lang.annotation.control.CodeGenerationHint;
22-
import org.springframework.beans.BeansException;
22+
2323
import org.springframework.beans.factory.BeanFactory;
2424
import org.springframework.beans.factory.BeanFactoryAware;
2525
import org.springframework.beans.factory.DisposableBean;
@@ -44,48 +44,47 @@ import org.springframework.beans.factory.wiring.BeanConfigurerSupport;
4444
* @see org.springframework.beans.factory.annotation.Configurable
4545
* @see org.springframework.beans.factory.annotation.AnnotationBeanWiringInfoResolver
4646
*/
47-
public aspect AnnotationBeanConfigurerAspect
48-
extends AbstractInterfaceDrivenDependencyInjectionAspect
47+
public aspect AnnotationBeanConfigurerAspect extends AbstractInterfaceDrivenDependencyInjectionAspect
4948
implements BeanFactoryAware, InitializingBean, DisposableBean {
5049

5150
private BeanConfigurerSupport beanConfigurerSupport = new BeanConfigurerSupport();
5251

53-
public pointcut inConfigurableBean() : @this(Configurable);
5452

55-
public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);
56-
57-
declare parents: @Configurable * implements ConfigurableObject;
58-
59-
public void configureBean(Object bean) {
60-
beanConfigurerSupport.configureBean(bean);
53+
public void setBeanFactory(BeanFactory beanFactory) {
54+
this.beanConfigurerSupport.setBeanFactory(beanFactory);
55+
this.beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
6156
}
6257

63-
64-
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
65-
beanConfigurerSupport.setBeanFactory(beanFactory);
66-
beanConfigurerSupport.setBeanWiringInfoResolver(new AnnotationBeanWiringInfoResolver());
58+
public void afterPropertiesSet() throws Exception {
59+
this.beanConfigurerSupport.afterPropertiesSet();
6760
}
6861

69-
public void afterPropertiesSet() throws Exception {
70-
beanConfigurerSupport.afterPropertiesSet();
62+
public void configureBean(Object bean) {
63+
this.beanConfigurerSupport.configureBean(bean);
7164
}
7265

7366
public void destroy() throws Exception {
74-
beanConfigurerSupport.destroy();
67+
this.beanConfigurerSupport.destroy();
7568
}
7669

7770

71+
public pointcut inConfigurableBean() : @this(Configurable);
72+
73+
public pointcut preConstructionConfiguration() : preConstructionConfigurationSupport(*);
74+
7875
/*
7976
* An intermediary to match preConstructionConfiguration signature (that doesn't expose the annotation object)
8077
*/
8178
@CodeGenerationHint(ifNameSuffix="bb0")
8279
private pointcut preConstructionConfigurationSupport(Configurable c) : @this(c) && if (c.preConstruction());
8380

81+
82+
declare parents: @Configurable * implements ConfigurableObject;
83+
8484
/*
8585
* This declaration shouldn't be needed,
8686
* except for an AspectJ bug (https://bugs.eclipse.org/bugs/show_bug.cgi?id=214559)
8787
*/
88-
declare parents: @Configurable Serializable+
89-
implements ConfigurableDeserializationSupport;
88+
declare parents: @Configurable Serializable+ implements ConfigurableDeserializationSupport;
9089

9190
}

spring-core/src/main/java/org/springframework/core/convert/Property.java

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2012 the original author or authors.
2+
* Copyright 2002-2014 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -62,6 +62,7 @@ public final class Property {
6262

6363
private Annotation[] annotations;
6464

65+
6566
public Property(Class<?> objectType, Method readMethod, Method writeMethod) {
6667
this(objectType, readMethod, writeMethod, null);
6768
}
@@ -241,34 +242,25 @@ private Class<?> declaringClass() {
241242
}
242243
}
243244

244-
@Override
245-
public int hashCode() {
246-
final int prime = 31;
247-
int hashCode = 1;
248-
hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.objectType);
249-
hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.readMethod);
250-
hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.writeMethod);
251-
hashCode = prime * hashCode + ObjectUtils.nullSafeHashCode(this.name);
252-
return hashCode;
253-
}
254245

255246
@Override
256-
public boolean equals(Object obj) {
257-
if (this == obj) {
247+
public boolean equals(Object other) {
248+
if (this == other) {
258249
return true;
259250
}
260-
if (obj == null) {
261-
return false;
262-
}
263-
if (getClass() != obj.getClass()) {
251+
if (!(other instanceof Property)) {
264252
return false;
265253
}
266-
Property other = (Property) obj;
267-
boolean equals = true;
268-
equals &= ObjectUtils.nullSafeEquals(this.objectType, other.objectType);
269-
equals &= ObjectUtils.nullSafeEquals(this.readMethod, other.readMethod);
270-
equals &= ObjectUtils.nullSafeEquals(this.writeMethod, other.writeMethod);
271-
equals &= ObjectUtils.nullSafeEquals(this.name, other.name);
272-
return equals;
254+
Property otherProperty = (Property) other;
255+
return (ObjectUtils.nullSafeEquals(this.objectType, otherProperty.objectType) &&
256+
ObjectUtils.nullSafeEquals(this.name, otherProperty.name) &&
257+
ObjectUtils.nullSafeEquals(this.readMethod, otherProperty.readMethod) &&
258+
ObjectUtils.nullSafeEquals(this.writeMethod, otherProperty.writeMethod));
273259
}
260+
261+
@Override
262+
public int hashCode() {
263+
return (ObjectUtils.nullSafeHashCode(this.objectType) * 31 + ObjectUtils.nullSafeHashCode(this.name));
264+
}
265+
274266
}

0 commit comments

Comments
 (0)