|
|
@ -51,6 +51,7 @@ import org.springframework.util.ReflectionUtils; |
|
|
|
* {@link GenericArrayType#getGenericComponentType()}) will be automatically wrapped. |
|
|
|
* {@link GenericArrayType#getGenericComponentType()}) will be automatically wrapped. |
|
|
|
* |
|
|
|
* |
|
|
|
* @author Phillip Webb |
|
|
|
* @author Phillip Webb |
|
|
|
|
|
|
|
* @author Juergen Hoeller |
|
|
|
* @since 4.0 |
|
|
|
* @since 4.0 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
abstract class SerializableTypeWrapper { |
|
|
|
abstract class SerializableTypeWrapper { |
|
|
@ -210,7 +211,7 @@ abstract class SerializableTypeWrapper { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* {@link Serializable} {@link InvocationHandler} used by the Proxied {@link Type}. |
|
|
|
* {@link Serializable} {@link InvocationHandler} used by the proxied {@link Type}. |
|
|
|
* Provides serialization support and enhances any methods that return {@code Type} |
|
|
|
* Provides serialization support and enhances any methods that return {@code Type} |
|
|
|
* or {@code Type[]}. |
|
|
|
* or {@code Type[]}. |
|
|
|
*/ |
|
|
|
*/ |
|
|
@ -373,21 +374,27 @@ abstract class SerializableTypeWrapper { |
|
|
|
|
|
|
|
|
|
|
|
private final int index; |
|
|
|
private final int index; |
|
|
|
|
|
|
|
|
|
|
|
private transient Object result; |
|
|
|
private transient Method method; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private transient volatile Object result; |
|
|
|
|
|
|
|
|
|
|
|
public MethodInvokeTypeProvider(TypeProvider provider, Method method, int index) { |
|
|
|
public MethodInvokeTypeProvider(TypeProvider provider, Method method, int index) { |
|
|
|
this.provider = provider; |
|
|
|
this.provider = provider; |
|
|
|
this.methodName = method.getName(); |
|
|
|
this.methodName = method.getName(); |
|
|
|
this.index = index; |
|
|
|
this.index = index; |
|
|
|
this.result = ReflectionUtils.invokeMethod(method, provider.getType()); |
|
|
|
this.method = method; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
|
public Type getType() { |
|
|
|
public Type getType() { |
|
|
|
if (this.result instanceof Type || this.result == null) { |
|
|
|
Object result = this.result; |
|
|
|
return (Type) this.result; |
|
|
|
if (result == null) { |
|
|
|
|
|
|
|
// Lazy invocation of the target method
|
|
|
|
|
|
|
|
result = ReflectionUtils.invokeMethod(this.method, this.provider.getType()); |
|
|
|
|
|
|
|
// Cache the result for further calls
|
|
|
|
|
|
|
|
this.result = result; |
|
|
|
} |
|
|
|
} |
|
|
|
return ((Type[])this.result)[this.index]; |
|
|
|
return (result instanceof Type[] ? ((Type[]) result)[this.index] : (Type) result); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -397,8 +404,8 @@ abstract class SerializableTypeWrapper { |
|
|
|
|
|
|
|
|
|
|
|
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException { |
|
|
|
private void readObject(ObjectInputStream inputStream) throws IOException, ClassNotFoundException { |
|
|
|
inputStream.defaultReadObject(); |
|
|
|
inputStream.defaultReadObject(); |
|
|
|
Method method = ReflectionUtils.findMethod(this.provider.getType().getClass(), this.methodName); |
|
|
|
this.method = ReflectionUtils.findMethod(this.provider.getType().getClass(), this.methodName); |
|
|
|
this.result = ReflectionUtils.invokeMethod(method, this.provider.getType()); |
|
|
|
Assert.state(this.method.getReturnType() == Type.class || this.method.getReturnType() == Type[].class); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|