MethodParameter generally uses volatile variables where applicable now (as well as a local copy of the parameterNameDiscoverer field)

Issue: SPR-12453
master
Juergen Hoeller 10 years ago
parent 1ef06cc743
commit 7fcadaa393
  1. 168
      spring-core/src/main/java/org/springframework/core/MethodParameter.java

@ -47,22 +47,22 @@ public class MethodParameter {
private final int parameterIndex; private final int parameterIndex;
private Class<?> containingClass; private int nestingLevel = 1;
private Class<?> parameterType; /** Map from Integer level to Integer type index */
Map<Integer, Integer> typeIndexesPerLevel;
private Type genericParameterType; private volatile Class<?> containingClass;
private Annotation[] parameterAnnotations; private volatile Class<?> parameterType;
private ParameterNameDiscoverer parameterNameDiscoverer; private volatile Type genericParameterType;
private String parameterName; private volatile Annotation[] parameterAnnotations;
private int nestingLevel = 1; private volatile ParameterNameDiscoverer parameterNameDiscoverer;
/** Map from Integer level to Integer type index */ private volatile String parameterName;
Map<Integer, Integer> typeIndexesPerLevel;
/** /**
@ -203,6 +203,73 @@ public class MethodParameter {
return this.parameterIndex; return this.parameterIndex;
} }
/**
* Increase this parameter's nesting level.
* @see #getNestingLevel()
*/
public void increaseNestingLevel() {
this.nestingLevel++;
}
/**
* Decrease this parameter's nesting level.
* @see #getNestingLevel()
*/
public void decreaseNestingLevel() {
getTypeIndexesPerLevel().remove(this.nestingLevel);
this.nestingLevel--;
}
/**
* Return the nesting level of the target type
* (typically 1; e.g. in case of a List of Lists, 1 would indicate the
* nested List, whereas 2 would indicate the element of the nested List).
*/
public int getNestingLevel() {
return this.nestingLevel;
}
/**
* Set the type index for the current nesting level.
* @param typeIndex the corresponding type index
* (or {@code null} for the default type index)
* @see #getNestingLevel()
*/
public void setTypeIndexForCurrentLevel(int typeIndex) {
getTypeIndexesPerLevel().put(this.nestingLevel, typeIndex);
}
/**
* Return the type index for the current nesting level.
* @return the corresponding type index, or {@code null}
* if none specified (indicating the default type index)
* @see #getNestingLevel()
*/
public Integer getTypeIndexForCurrentLevel() {
return getTypeIndexForLevel(this.nestingLevel);
}
/**
* Return the type index for the specified nesting level.
* @param nestingLevel the nesting level to check
* @return the corresponding type index, or {@code null}
* if none specified (indicating the default type index)
*/
public Integer getTypeIndexForLevel(int nestingLevel) {
return getTypeIndexesPerLevel().get(nestingLevel);
}
/**
* Obtain the (lazily constructed) type-indexes-per-level Map.
*/
private Map<Integer, Integer> getTypeIndexesPerLevel() {
if (this.typeIndexesPerLevel == null) {
this.typeIndexesPerLevel = new HashMap<Integer, Integer>(4);
}
return this.typeIndexesPerLevel;
}
/** /**
* Set a containing class to resolve the parameter type against. * Set a containing class to resolve the parameter type against.
*/ */
@ -364,10 +431,10 @@ public class MethodParameter {
* has been set to begin with) * has been set to begin with)
*/ */
public String getParameterName() { public String getParameterName() {
if (this.parameterNameDiscoverer != null) { ParameterNameDiscoverer discoverer = this.parameterNameDiscoverer;
if (discoverer != null) {
String[] parameterNames = (this.method != null ? String[] parameterNames = (this.method != null ?
this.parameterNameDiscoverer.getParameterNames(this.method) : discoverer.getParameterNames(this.method) : discoverer.getParameterNames(this.constructor));
this.parameterNameDiscoverer.getParameterNames(this.constructor));
if (parameterNames != null) { if (parameterNames != null) {
this.parameterName = parameterNames[this.parameterIndex]; this.parameterName = parameterNames[this.parameterIndex];
} }
@ -376,82 +443,17 @@ public class MethodParameter {
return this.parameterName; return this.parameterName;
} }
/**
* Increase this parameter's nesting level.
* @see #getNestingLevel()
*/
public void increaseNestingLevel() {
this.nestingLevel++;
}
/**
* Decrease this parameter's nesting level.
* @see #getNestingLevel()
*/
public void decreaseNestingLevel() {
getTypeIndexesPerLevel().remove(this.nestingLevel);
this.nestingLevel--;
}
/**
* Return the nesting level of the target type
* (typically 1; e.g. in case of a List of Lists, 1 would indicate the
* nested List, whereas 2 would indicate the element of the nested List).
*/
public int getNestingLevel() {
return this.nestingLevel;
}
/**
* Set the type index for the current nesting level.
* @param typeIndex the corresponding type index
* (or {@code null} for the default type index)
* @see #getNestingLevel()
*/
public void setTypeIndexForCurrentLevel(int typeIndex) {
getTypeIndexesPerLevel().put(this.nestingLevel, typeIndex);
}
/**
* Return the type index for the current nesting level.
* @return the corresponding type index, or {@code null}
* if none specified (indicating the default type index)
* @see #getNestingLevel()
*/
public Integer getTypeIndexForCurrentLevel() {
return getTypeIndexForLevel(this.nestingLevel);
}
/**
* Return the type index for the specified nesting level.
* @param nestingLevel the nesting level to check
* @return the corresponding type index, or {@code null}
* if none specified (indicating the default type index)
*/
public Integer getTypeIndexForLevel(int nestingLevel) {
return getTypeIndexesPerLevel().get(nestingLevel);
}
/**
* Obtain the (lazily constructed) type-indexes-per-level Map.
*/
private Map<Integer, Integer> getTypeIndexesPerLevel() {
if (this.typeIndexesPerLevel == null) {
this.typeIndexesPerLevel = new HashMap<Integer, Integer>(4);
}
return this.typeIndexesPerLevel;
}
@Override @Override
public boolean equals(Object obj) { public boolean equals(Object other) {
if (this == obj) { if (this == other) {
return true; return true;
} }
if (obj != null && obj instanceof MethodParameter) { if (!(other instanceof MethodParameter)) {
MethodParameter other = (MethodParameter) obj; return false;
return (this.parameterIndex == other.parameterIndex && getMember().equals(other.getMember()));
} }
return false; MethodParameter otherParam = (MethodParameter) other;
return (this.parameterIndex == otherParam.parameterIndex && getMember().equals(otherParam.getMember()));
} }
@Override @Override

Loading…
Cancel
Save