Consistent use of @Nullable in spring-test
This commit also removes nullability from two common spots: ResolvableType.getType() and TargetSource.getTarget(), both of which are never effectively null with any regular implementation. For such scenarios, a non-null empty type/target is the cleaner contract. Issue: SPR-15540
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.aop;
|
||||
|
||||
import org.springframework.lang.Nullable;
|
||||
|
||||
/**
|
||||
* A {@code TargetSource} is used to obtain the current "target" of
|
||||
* an AOP invocation, which will be invoked via reflection if no around
|
||||
@@ -59,7 +57,6 @@ public interface TargetSource extends TargetClassAware {
|
||||
* @return the target object, which contains the joinpoint
|
||||
* @throws Exception if the target object can't be resolved
|
||||
*/
|
||||
@Nullable
|
||||
Object getTarget() throws Exception;
|
||||
|
||||
/**
|
||||
|
||||
@@ -326,8 +326,12 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
// TODO: small memory optimization here (can skip creation for methods with no advice)
|
||||
for (int x = 0; x < methods.length; x++) {
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
|
||||
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
|
||||
chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
|
||||
Object target = this.advised.getTargetSource().getTarget();
|
||||
Class<?> targetClass = this.advised.getTargetClass();
|
||||
if (targetClass == null) {
|
||||
targetClass = target.getClass();
|
||||
}
|
||||
fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(chain, target, targetClass);
|
||||
this.fixedInterceptorMap.put(methods[x].toString(), x);
|
||||
}
|
||||
|
||||
@@ -374,7 +378,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
* {@code proxy} and also verifies that {@code null} is not returned as a primitive.
|
||||
*/
|
||||
@Nullable
|
||||
private static Object processReturnType(Object proxy, @Nullable Object target, Method method, @Nullable Object retVal) {
|
||||
private static Object processReturnType(Object proxy, Object target, Method method, @Nullable Object retVal) {
|
||||
// Massage return value if necessary
|
||||
if (retVal != null && retVal == target &&
|
||||
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
|
||||
@@ -409,7 +413,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final Object target;
|
||||
|
||||
public StaticUnadvisedInterceptor(@Nullable Object target) {
|
||||
public StaticUnadvisedInterceptor(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -430,7 +434,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final Object target;
|
||||
|
||||
public StaticUnadvisedExposedInterceptor(@Nullable Object target) {
|
||||
public StaticUnadvisedExposedInterceptor(Object target) {
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
@@ -472,9 +476,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return processReturnType(proxy, target, method, retVal);
|
||||
}
|
||||
finally {
|
||||
if (target != null) {
|
||||
this.targetSource.releaseTarget(target);
|
||||
}
|
||||
this.targetSource.releaseTarget(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -503,9 +505,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
}
|
||||
finally {
|
||||
AopContext.setCurrentProxy(oldProxy);
|
||||
if (target != null) {
|
||||
this.targetSource.releaseTarget(target);
|
||||
}
|
||||
this.targetSource.releaseTarget(target);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -612,9 +612,7 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final Class<?> targetClass;
|
||||
|
||||
public FixedChainStaticTargetInterceptor(
|
||||
List<Object> adviceChain, @Nullable Object target, @Nullable Class<?> targetClass) {
|
||||
|
||||
public FixedChainStaticTargetInterceptor(List<Object> adviceChain, Object target, Class<?> targetClass) {
|
||||
this.adviceChain = adviceChain;
|
||||
this.target = target;
|
||||
this.targetClass = targetClass;
|
||||
@@ -650,7 +648,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
|
||||
Object oldProxy = null;
|
||||
boolean setProxyContext = false;
|
||||
Class<?> targetClass = null;
|
||||
Object target = null;
|
||||
try {
|
||||
if (this.advised.exposeProxy) {
|
||||
@@ -658,12 +655,9 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
oldProxy = AopContext.setCurrentProxy(proxy);
|
||||
setProxyContext = true;
|
||||
}
|
||||
// May be null. Get as late as possible to minimize the time we
|
||||
// "own" the target, in case it comes from a pool...
|
||||
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
|
||||
target = getTarget();
|
||||
if (target != null) {
|
||||
targetClass = target.getClass();
|
||||
}
|
||||
Class<?> targetClass = target.getClass();
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||
Object retVal;
|
||||
// Check whether we only have one InvokerInterceptor: that is,
|
||||
@@ -709,7 +703,6 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
return this.advised.hashCode();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Object getTarget() throws Exception {
|
||||
return this.advised.getTargetSource().getTarget();
|
||||
}
|
||||
@@ -729,9 +722,8 @@ class CglibAopProxy implements AopProxy, Serializable {
|
||||
|
||||
private final boolean publicMethod;
|
||||
|
||||
public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method,
|
||||
Object[] arguments, @Nullable Class<?> targetClass,
|
||||
List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
|
||||
|
||||
super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
|
||||
this.methodProxy = methodProxy;
|
||||
|
||||
@@ -159,7 +159,6 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
boolean setProxyContext = false;
|
||||
|
||||
TargetSource targetSource = this.advised.targetSource;
|
||||
Class<?> targetClass = null;
|
||||
Object target = null;
|
||||
|
||||
try {
|
||||
@@ -189,12 +188,10 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
|
||||
setProxyContext = true;
|
||||
}
|
||||
|
||||
// May be null. Get as late as possible to minimize the time we "own" the target,
|
||||
// Get as late as possible to minimize the time we "own" the target,
|
||||
// in case it comes from a pool.
|
||||
target = targetSource.getTarget();
|
||||
if (target != null) {
|
||||
targetClass = target.getClass();
|
||||
}
|
||||
Class<?> targetClass = target.getClass();
|
||||
|
||||
// Get the interception chain for this method.
|
||||
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|
||||
|
||||
@@ -103,8 +103,8 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
|
||||
* but would complicate the code. And it would work only for static pointcuts.
|
||||
*/
|
||||
protected ReflectiveMethodInvocation(
|
||||
Object proxy, @Nullable Object target, Method method, Object[] arguments,
|
||||
@Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
Object proxy, Object target, Method method, Object[] arguments,
|
||||
Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {
|
||||
|
||||
this.proxy = proxy;
|
||||
this.target = target;
|
||||
|
||||
@@ -329,7 +329,7 @@ public abstract class AopUtils {
|
||||
* @throws org.springframework.aop.AopInvocationException in case of a reflection error
|
||||
*/
|
||||
@Nullable
|
||||
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args)
|
||||
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
|
||||
throws Throwable {
|
||||
|
||||
// Use reflection to invoke the method.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2012 the original author or authors.
|
||||
* Copyright 2002-2017 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.
|
||||
@@ -32,6 +32,13 @@ import org.springframework.util.ObjectUtils;
|
||||
*/
|
||||
public class EmptyTargetSource implements TargetSource, Serializable {
|
||||
|
||||
/**
|
||||
* The canonical (Singleton) instance of this {@link EmptyTargetSource}.
|
||||
*/
|
||||
public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(null, true);
|
||||
|
||||
private static final Object EMPTY_TARGET = new Object();
|
||||
|
||||
/** use serialVersionUID from Spring 1.2 for interoperability */
|
||||
private static final long serialVersionUID = 3680494563553489691L;
|
||||
|
||||
@@ -40,12 +47,6 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||
// Static factory methods
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* The canonical (Singleton) instance of this {@link EmptyTargetSource}.
|
||||
*/
|
||||
public static final EmptyTargetSource INSTANCE = new EmptyTargetSource(null, true);
|
||||
|
||||
|
||||
/**
|
||||
* Return an EmptyTargetSource for the given target Class.
|
||||
* @param targetClass the target Class (may be {@code null})
|
||||
@@ -87,6 +88,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||
this.isStatic = isStatic;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Always returns the specified target Class, or {@code null} if none.
|
||||
*/
|
||||
@@ -104,11 +106,11 @@ public class EmptyTargetSource implements TargetSource, Serializable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Always returns {@code null}.
|
||||
* Always returns {@code DUMMY_TARGET}.
|
||||
*/
|
||||
@Override
|
||||
public Object getTarget() {
|
||||
return null;
|
||||
return EMPTY_TARGET;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user