Browse Source

Specify generic type nullness in spring-aop

See gh-34140
pull/34266/head
Sébastien Deleuze 11 months ago
parent
commit
f52f83349c
  1. 4
      spring-aop/src/main/java/org/springframework/aop/AfterReturningAdvice.java
  2. 4
      spring-aop/src/main/java/org/springframework/aop/MethodBeforeAdvice.java
  3. 18
      spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java
  4. 4
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java
  5. 4
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java
  6. 4
      spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java
  7. 14
      spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java
  8. 4
      spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java
  9. 4
      spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java
  10. 4
      spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java
  11. 4
      spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java
  12. 6
      spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java

4
spring-aop/src/main/java/org/springframework/aop/AfterReturningAdvice.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2012 the original author or authors.
* Copyright 2002-2025 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.
@ -41,6 +41,6 @@ public interface AfterReturningAdvice extends AfterAdvice { @@ -41,6 +41,6 @@ public interface AfterReturningAdvice extends AfterAdvice {
* allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception.
*/
void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable;
void afterReturning(@Nullable Object returnValue, Method method, @Nullable Object[] args, @Nullable Object target) throws Throwable;
}

4
spring-aop/src/main/java/org/springframework/aop/MethodBeforeAdvice.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2025 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.
@ -40,6 +40,6 @@ public interface MethodBeforeAdvice extends BeforeAdvice { @@ -40,6 +40,6 @@ public interface MethodBeforeAdvice extends BeforeAdvice {
* allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception.
*/
void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
void before(Method method, @Nullable Object[] args, @Nullable Object target) throws Throwable;
}

18
spring-aop/src/main/java/org/springframework/aop/aspectj/AbstractAspectJAdvice.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
@ -43,6 +43,7 @@ import org.springframework.aop.support.MethodMatchers; @@ -43,6 +43,7 @@ import org.springframework.aop.support.MethodMatchers;
import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Contract;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils;
@ -258,10 +259,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence @@ -258,10 +259,11 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* or in an advice annotation.
* @param argumentNames list of argument names
*/
public void setArgumentNamesFromStringArray(String... argumentNames) {
public void setArgumentNamesFromStringArray(@Nullable String... argumentNames) {
this.argumentNames = new String[argumentNames.length];
for (int i = 0; i < argumentNames.length; i++) {
this.argumentNames[i] = argumentNames[i].strip();
String argumentName = argumentNames[i];
this.argumentNames[i] = argumentName != null ? argumentName.strip() : null;
if (!isVariableName(this.argumentNames[i])) {
throw new IllegalArgumentException(
"'argumentNames' property of AbstractAspectJAdvice contains an argument name '" +
@ -274,7 +276,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence @@ -274,7 +276,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
if (firstArgType == JoinPoint.class ||
firstArgType == ProceedingJoinPoint.class ||
firstArgType == JoinPoint.StaticPart.class) {
String[] oldNames = this.argumentNames;
@Nullable String[] oldNames = this.argumentNames;
this.argumentNames = new String[oldNames.length + 1];
this.argumentNames[0] = "THIS_JOIN_POINT";
System.arraycopy(oldNames, 0, this.argumentNames, 1, oldNames.length);
@ -346,7 +348,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence @@ -346,7 +348,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return this.discoveredThrowingType;
}
private static boolean isVariableName(String name) {
@Contract("null -> false")
private static boolean isVariableName(@Nullable String name) {
return AspectJProxyUtils.isVariableName(name);
}
@ -456,6 +459,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence @@ -456,6 +459,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return discoverer;
}
@SuppressWarnings("NullAway") // Dataflow analysis limitation
private void bindExplicitArguments(int numArgumentsLeftToBind) {
Assert.state(this.argumentNames != null, "No argument names available");
this.argumentBindings = new HashMap<>();
@ -623,8 +627,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence @@ -623,8 +627,8 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t));
}
protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable {
Object[] actualArgs = args;
protected Object invokeAdviceMethodWithGivenArgs(@Nullable Object[] args) throws Throwable {
@Nullable Object[] actualArgs = args;
if (this.aspectJAdviceMethod.getParameterCount() == 0) {
actualArgs = null;
}

4
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJAfterReturningAdvice.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2025 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,7 +62,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice @@ -62,7 +62,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
}
@Override
public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable {
public void afterReturning(@Nullable Object returnValue, Method method, @Nullable Object[] args, @Nullable Object target) throws Throwable {
if (shouldInvokeOnReturnValueOf(method, returnValue)) {
invokeAdviceMethod(getJoinPointMatch(), returnValue, null);
}

4
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJMethodBeforeAdvice.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2015 the original author or authors.
* Copyright 2002-2025 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.
@ -41,7 +41,7 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements @@ -41,7 +41,7 @@ public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements
@Override
public void before(Method method, Object[] args, @Nullable Object target) throws Throwable {
public void before(Method method, @Nullable Object[] args, @Nullable Object target) throws Throwable {
invokeAdviceMethod(getJoinPointMatch(), null, null);
}

4
spring-aop/src/main/java/org/springframework/aop/aspectj/AspectJProxyUtils.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2022 the original author or authors.
* Copyright 2002-2025 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.
@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable; @@ -23,6 +23,7 @@ import org.jspecify.annotations.Nullable;
import org.springframework.aop.Advisor;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.interceptor.ExposeInvocationInterceptor;
import org.springframework.lang.Contract;
import org.springframework.util.StringUtils;
/**
@ -76,6 +77,7 @@ public abstract class AspectJProxyUtils { @@ -76,6 +77,7 @@ public abstract class AspectJProxyUtils {
pointcutAdvisor.getPointcut() instanceof AspectJExpressionPointcut));
}
@Contract("null -> false")
static boolean isVariableName(@Nullable String name) {
if (!StringUtils.hasLength(name)) {
return false;

14
spring-aop/src/main/java/org/springframework/aop/aspectj/MethodInvocationProceedingJoinPoint.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
@ -55,7 +55,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, @@ -55,7 +55,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
private final ProxyMethodInvocation methodInvocation;
private Object @Nullable [] args;
private @Nullable Object @Nullable [] args;
/** Lazily initialized signature object. */
private @Nullable Signature signature;
@ -114,7 +114,8 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, @@ -114,7 +114,8 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
}
@Override
public Object[] getArgs() {
@SuppressWarnings("NullAway") // Overridden method does not define nullness
public @Nullable Object[] getArgs() {
if (this.args == null) {
this.args = this.methodInvocation.getArguments().clone();
}
@ -174,7 +175,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, @@ -174,7 +175,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
*/
private class MethodSignatureImpl implements MethodSignature {
private volatile String @Nullable [] parameterNames;
private volatile @Nullable String @Nullable [] parameterNames;
@Override
public String getName() {
@ -212,8 +213,9 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint, @@ -212,8 +213,9 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
}
@Override
public String @Nullable [] getParameterNames() {
String[] parameterNames = this.parameterNames;
@SuppressWarnings("NullAway") // Overridden method does not define nullness
public @Nullable String @Nullable [] getParameterNames() {
@Nullable String[] parameterNames = this.parameterNames;
if (parameterNames == null) {
parameterNames = parameterNameDiscoverer.getParameterNames(getMethod());
this.parameterNames = parameterNames;

4
spring-aop/src/main/java/org/springframework/aop/aspectj/annotation/ReflectiveAspectJAdvisorFactory.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -302,7 +302,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto @@ -302,7 +302,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
@Nullable String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}

4
spring-aop/src/main/java/org/springframework/aop/framework/CglibAopProxy.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -704,7 +704,7 @@ class CglibAopProxy implements AopProxy, Serializable { @@ -704,7 +704,7 @@ class CglibAopProxy implements AopProxy, Serializable {
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
@Nullable Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {

4
spring-aop/src/main/java/org/springframework/aop/framework/JdkDynamicAopProxy.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -211,7 +211,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa @@ -211,7 +211,7 @@ final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializa
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
@Nullable Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {

4
spring-aop/src/main/java/org/springframework/aop/framework/ReflectiveMethodInvocation.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2023 the original author or authors.
* Copyright 2002-2025 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.
@ -201,7 +201,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea @@ -201,7 +201,7 @@ public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Clonea
*/
@Override
public MethodInvocation invocableClone() {
Object[] cloneArguments = this.arguments;
@Nullable Object[] cloneArguments = this.arguments;
if (this.arguments.length > 0) {
// Build an independent copy of the arguments array.
cloneArguments = this.arguments.clone();

6
spring-aop/src/main/java/org/springframework/aop/interceptor/AsyncExecutionAspectSupport.java

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright 2002-2024 the original author or authors.
* Copyright 2002-2025 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.
@ -116,8 +116,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware { @@ -116,8 +116,8 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* applying the corresponding default if a supplier is not resolvable.
* @since 5.1
*/
public void configure(@Nullable Supplier<Executor> defaultExecutor,
@Nullable Supplier<AsyncUncaughtExceptionHandler> exceptionHandler) {
public void configure(@Nullable Supplier<? extends @Nullable Executor> defaultExecutor,
@Nullable Supplier<? extends @Nullable AsyncUncaughtExceptionHandler> exceptionHandler) {
this.defaultExecutor = new SingletonSupplier<>(defaultExecutor, () -> getDefaultExecutor(this.beanFactory));
this.exceptionHandler = new SingletonSupplier<>(exceptionHandler, SimpleAsyncUncaughtExceptionHandler::new);

Loading…
Cancel
Save