Introduce null-safety of Spring Framework API

This commit introduces 2 new @Nullable and @NonNullApi
annotations that leverage JSR 305 (dormant but available via
Findbugs jsr305 dependency and already used by libraries
like OkHttp) meta-annotations to specify explicitly
null-safety of Spring Framework parameters and return values.

In order to avoid adding too much annotations, the
default is set at package level with @NonNullApi and
@Nullable annotations are added when needed at parameter or
return value level. These annotations are intended to be used
on Spring Framework itself but also by other Spring projects.

@Nullable annotations have been introduced based on Javadoc
and search of patterns like "return null;". It is expected that
nullability of Spring Framework API will be polished with
complementary commits.

In practice, this will make the whole Spring Framework API
null-safe for Kotlin projects (when KT-10942 will be fixed)
since Kotlin will be able to leverage these annotations to
know if a parameter or a return value is nullable or not. But
this is also useful for Java developers as well since IntelliJ
IDEA, for example, also understands these annotations to
generate warnings when unsafe nullable usages are detected.

Issue: SPR-15540
This commit is contained in:
Sebastien Deleuze 2017-05-27 08:14:59 +02:00
parent 2d37c966b2
commit 87598f48e4
1315 changed files with 4831 additions and 963 deletions

View File

@ -177,6 +177,7 @@ configure(allprojects) { project ->
} }
dependencies { dependencies {
provided("com.google.code.findbugs:jsr305:3.0.2")
testCompile("junit:junit:${junitVersion}") { testCompile("junit:junit:${junitVersion}") {
exclude group:'org.hamcrest', module:'hamcrest-core' exclude group:'org.hamcrest', module:'hamcrest-core'
} }

View File

@ -16,6 +16,8 @@
package org.aopalliance.aop; package org.aopalliance.aop;
import org.springframework.lang.Nullable;
/** /**
* Superclass for all AOP infrastructure exceptions. * Superclass for all AOP infrastructure exceptions.
* Unchecked, as such exceptions are fatal and end user * Unchecked, as such exceptions are fatal and end user
@ -41,7 +43,7 @@ public class AspectException extends RuntimeException {
* @param message the exception message * @param message the exception message
* @param cause the root cause, if any * @param cause the root cause, if any
*/ */
public AspectException(String message, Throwable cause) { public AspectException(String message, @Nullable Throwable cause) {
super(message, cause); super(message, cause);
} }

View File

@ -16,6 +16,8 @@
package org.aopalliance.intercept; package org.aopalliance.intercept;
import org.springframework.lang.Nullable;
/** /**
* Intercepts calls on an interface on its way to the target. These * Intercepts calls on an interface on its way to the target. These
* are nested "on top" of the target. * are nested "on top" of the target.
@ -52,6 +54,7 @@ public interface MethodInterceptor extends Interceptor {
* @throws Throwable if the interceptors or the target object * @throws Throwable if the interceptors or the target object
* throws an exception * throws an exception
*/ */
@Nullable
Object invoke(MethodInvocation invocation) throws Throwable; Object invoke(MethodInvocation invocation) throws Throwable;
} }

View File

@ -18,6 +18,8 @@ package org.springframework.aop;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.lang.Nullable;
/** /**
* After returning advice is invoked only on normal method return, not if an * After returning advice is invoked only on normal method return, not if an
* exception is thrown. Such advice can see the return value, but cannot change it. * exception is thrown. Such advice can see the return value, but cannot change it.
@ -39,6 +41,6 @@ public interface AfterReturningAdvice extends AfterAdvice {
* allowed by the method signature. Otherwise the exception * allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception. * will be wrapped as a runtime exception.
*/ */
void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable; void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable;
} }

View File

@ -18,6 +18,8 @@ package org.springframework.aop;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.lang.Nullable;
/** /**
* A specialized type of {@link MethodMatcher} that takes into account introductions * A specialized type of {@link MethodMatcher} that takes into account introductions
* when matching methods. If there are no introductions on the target class, * when matching methods. If there are no introductions on the target class,
@ -39,6 +41,6 @@ public interface IntroductionAwareMethodMatcher extends MethodMatcher {
* asking is the subject on one or more introductions; {@code false} otherwise * asking is the subject on one or more introductions; {@code false} otherwise
* @return whether or not this method matches statically * @return whether or not this method matches statically
*/ */
boolean matches(Method method, Class<?> targetClass, boolean hasIntroductions); boolean matches(Method method, @Nullable Class<?> targetClass, boolean hasIntroductions);
} }

View File

@ -18,6 +18,8 @@ package org.springframework.aop;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.lang.Nullable;
/** /**
* Advice invoked before a method is invoked. Such advices cannot * Advice invoked before a method is invoked. Such advices cannot
* prevent the method call proceeding, unless they throw a Throwable. * prevent the method call proceeding, unless they throw a Throwable.
@ -39,6 +41,6 @@ public interface MethodBeforeAdvice extends BeforeAdvice {
* allowed by the method signature. Otherwise the exception * allowed by the method signature. Otherwise the exception
* will be wrapped as a runtime exception. * will be wrapped as a runtime exception.
*/ */
void before(Method method, Object[] args, Object target) throws Throwable; void before(Method method, Object[] args, @Nullable Object target) throws Throwable;
} }

View File

@ -18,6 +18,8 @@ package org.springframework.aop;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.lang.Nullable;
/** /**
* Part of a {@link Pointcut}: Checks whether the target method is eligible for advice. * Part of a {@link Pointcut}: Checks whether the target method is eligible for advice.
* *
@ -57,7 +59,7 @@ public interface MethodMatcher {
* the candidate class must be taken to be the method's declaring class) * the candidate class must be taken to be the method's declaring class)
* @return whether or not this method matches statically * @return whether or not this method matches statically
*/ */
boolean matches(Method method, Class<?> targetClass); boolean matches(Method method, @Nullable Class<?> targetClass);
/** /**
* Is this MethodMatcher dynamic, that is, must a final call be made on the * Is this MethodMatcher dynamic, that is, must a final call be made on the
@ -86,7 +88,7 @@ public interface MethodMatcher {
* @return whether there's a runtime match * @return whether there's a runtime match
* @see MethodMatcher#matches(Method, Class) * @see MethodMatcher#matches(Method, Class)
*/ */
boolean matches(Method method, Class<?> targetClass, Object... args); boolean matches(Method method, @Nullable Class<?> targetClass, Object... args);
/** /**

View File

@ -18,6 +18,8 @@ package org.springframework.aop;
import org.aopalliance.intercept.MethodInvocation; import org.aopalliance.intercept.MethodInvocation;
import org.springframework.lang.Nullable;
/** /**
* Extension of the AOP Alliance {@link org.aopalliance.intercept.MethodInvocation} * Extension of the AOP Alliance {@link org.aopalliance.intercept.MethodInvocation}
* interface, allowing access to the proxy that the method invocation was made through. * interface, allowing access to the proxy that the method invocation was made through.
@ -73,7 +75,7 @@ public interface ProxyMethodInvocation extends MethodInvocation {
* @param key the name of the attribute * @param key the name of the attribute
* @param value the value of the attribute, or {@code null} to reset it * @param value the value of the attribute, or {@code null} to reset it
*/ */
void setUserAttribute(String key, Object value); void setUserAttribute(String key, @Nullable Object value);
/** /**
* Return the value of the specified user attribute. * Return the value of the specified user attribute.
@ -81,6 +83,7 @@ public interface ProxyMethodInvocation extends MethodInvocation {
* @return the value of the attribute, or {@code null} if not set * @return the value of the attribute, or {@code null} if not set
* @see #setUserAttribute * @see #setUserAttribute
*/ */
@Nullable
Object getUserAttribute(String key); Object getUserAttribute(String key);
} }

View File

@ -16,6 +16,8 @@
package org.springframework.aop; package org.springframework.aop;
import org.springframework.lang.Nullable;
/** /**
* Minimal interface for exposing the target class behind a proxy. * Minimal interface for exposing the target class behind a proxy.
* *
@ -34,6 +36,7 @@ public interface TargetClassAware {
* (typically a proxy configuration or an actual proxy). * (typically a proxy configuration or an actual proxy).
* @return the target Class, or {@code null} if not known * @return the target Class, or {@code null} if not known
*/ */
@Nullable
Class<?> getTargetClass(); Class<?> getTargetClass();
} }

View File

@ -16,6 +16,8 @@
package org.springframework.aop; package org.springframework.aop;
import org.springframework.lang.Nullable;
/** /**
* A {@code TargetSource} is used to obtain the current "target" of * A {@code TargetSource} is used to obtain the current "target" of
* an AOP invocation, which will be invoked via reflection if no around * an AOP invocation, which will be invoked via reflection if no around
@ -58,6 +60,7 @@ public interface TargetSource extends TargetClassAware {
* @return the target object, which contains the joinpoint * @return the target object, which contains the joinpoint
* @throws Exception if the target object can't be resolved * @throws Exception if the target object can't be resolved
*/ */
@Nullable
Object getTarget() throws Exception; Object getTarget() throws Exception;
/** /**

View File

@ -42,6 +42,7 @@ import org.springframework.aop.support.MethodMatchers;
import org.springframework.aop.support.StaticMethodMatcher; import org.springframework.aop.support.StaticMethodMatcher;
import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
@ -548,7 +549,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* @param ex the exception thrown by the method execution (may be null) * @param ex the exception thrown by the method execution (may be null)
* @return the empty array if there are no arguments * @return the empty array if there are no arguments
*/ */
protected Object[] argBinding(JoinPoint jp, JoinPointMatch jpMatch, Object returnValue, Throwable ex) { protected Object[] argBinding(JoinPoint jp, JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) {
calculateArgumentBindings(); calculateArgumentBindings();
// AMC start // AMC start
@ -607,7 +608,7 @@ public abstract class AbstractAspectJAdvice implements Advice, AspectJPrecedence
* @return the invocation result * @return the invocation result
* @throws Throwable in case of invocation failure * @throws Throwable in case of invocation failure
*/ */
protected Object invokeAdviceMethod(JoinPointMatch jpMatch, Object returnValue, Throwable ex) throws Throwable { protected Object invokeAdviceMethod(JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex));
} }

View File

@ -30,6 +30,7 @@ import org.aspectj.weaver.tools.PointcutParser;
import org.aspectj.weaver.tools.PointcutPrimitive; import org.aspectj.weaver.tools.PointcutPrimitive;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -473,6 +474,7 @@ public class AspectJAdviceParameterNameDiscoverer implements ParameterNameDiscov
/* /*
* If the token starts meets Java identifier conventions, it's in. * If the token starts meets Java identifier conventions, it's in.
*/ */
@Nullable
private String maybeExtractVariableName(String candidateToken) { private String maybeExtractVariableName(String candidateToken) {
if (candidateToken == null || candidateToken.equals("")) { if (candidateToken == null || candidateToken.equals("")) {
return null; return null;

View File

@ -22,6 +22,7 @@ import java.lang.reflect.Type;
import org.springframework.aop.AfterAdvice; import org.springframework.aop.AfterAdvice;
import org.springframework.aop.AfterReturningAdvice; import org.springframework.aop.AfterReturningAdvice;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.TypeUtils; import org.springframework.util.TypeUtils;
@ -75,7 +76,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
* @param returnValue the return value of the target method * @param returnValue the return value of the target method
* @return whether to invoke the advice method for the given return value * @return whether to invoke the advice method for the given return value
*/ */
private boolean shouldInvokeOnReturnValueOf(Method method, Object returnValue) { private boolean shouldInvokeOnReturnValueOf(Method method, @Nullable Object returnValue) {
Class<?> type = getDiscoveredReturningType(); Class<?> type = getDiscoveredReturningType();
Type genericType = getDiscoveredReturningGenericType(); Type genericType = getDiscoveredReturningGenericType();
// If we aren't dealing with a raw type, check if generic parameters are assignable. // If we aren't dealing with a raw type, check if generic parameters are assignable.
@ -94,7 +95,7 @@ public class AspectJAfterReturningAdvice extends AbstractAspectJAdvice
* @param returnValue the return value of the target method * @param returnValue the return value of the target method
* @return whether to invoke the advice method for the given return value and type * @return whether to invoke the advice method for the given return value and type
*/ */
private boolean matchesReturnValue(Class<?> type, Method method, Object returnValue) { private boolean matchesReturnValue(Class<?> type, Method method, @Nullable Object returnValue) {
if (returnValue != null) { if (returnValue != null) {
return ClassUtils.isAssignableValue(type, returnValue); return ClassUtils.isAssignableValue(type, returnValue);
} }

View File

@ -21,6 +21,7 @@ import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor; import org.springframework.aop.Advisor;
import org.springframework.aop.AfterAdvice; import org.springframework.aop.AfterAdvice;
import org.springframework.aop.BeforeAdvice; import org.springframework.aop.BeforeAdvice;
import org.springframework.lang.Nullable;
/** /**
* Utility methods for dealing with AspectJ advisors. * Utility methods for dealing with AspectJ advisors.
@ -58,6 +59,7 @@ public abstract class AspectJAopUtils {
* If neither the advisor nor the advice have precedence information, this method * If neither the advisor nor the advice have precedence information, this method
* will return {@code null}. * will return {@code null}.
*/ */
@Nullable
public static AspectJPrecedenceInformation getAspectJPrecedenceInformationFor(Advisor anAdvisor) { public static AspectJPrecedenceInformation getAspectJPrecedenceInformationFor(Advisor anAdvisor) {
if (anAdvisor instanceof AspectJPrecedenceInformation) { if (anAdvisor instanceof AspectJPrecedenceInformation) {
return (AspectJPrecedenceInformation) anAdvisor; return (AspectJPrecedenceInformation) anAdvisor;

View File

@ -56,6 +56,7 @@ import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils; import org.springframework.beans.factory.annotation.BeanFactoryAnnotationUtils;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -382,6 +383,7 @@ public class AspectJExpressionPointcut extends AbstractExpressionPointcut
/** /**
* Get a new pointcut expression based on a target class's loader rather than the default. * Get a new pointcut expression based on a target class's loader rather than the default.
*/ */
@Nullable
private PointcutExpression getFallbackPointcutExpression(Class<?> targetClass) { private PointcutExpression getFallbackPointcutExpression(Class<?> targetClass) {
try { try {
ClassLoader classLoader = targetClass.getClassLoader(); ClassLoader classLoader = targetClass.getClassLoader();

View File

@ -29,6 +29,7 @@ import org.aspectj.runtime.internal.AroundClosure;
import org.springframework.aop.ProxyMethodInvocation; import org.springframework.aop.ProxyMethodInvocation;
import org.springframework.core.DefaultParameterNameDiscoverer; import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -109,6 +110,7 @@ public class MethodInvocationProceedingJoinPoint implements ProceedingJoinPoint,
* Returns the Spring AOP target. May be {@code null} if there is no target. * Returns the Spring AOP target. May be {@code null} if there is no target.
*/ */
@Override @Override
@Nullable
public Object getTarget() { public Object getTarget() {
return this.methodInvocation.getThis(); return this.methodInvocation.getThis();
} }

View File

@ -41,6 +41,7 @@ import org.aspectj.lang.reflect.PerClauseKind;
import org.springframework.aop.framework.AopConfigException; import org.springframework.aop.framework.AopConfigException;
import org.springframework.core.ParameterNameDiscoverer; import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -125,6 +126,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
* (there <i>should</i> only be one anyway...) * (there <i>should</i> only be one anyway...)
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Nullable
protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) { protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
Class<?>[] classesToLookFor = new Class<?>[] { Class<?>[] classesToLookFor = new Class<?>[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class}; Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
@ -137,6 +139,7 @@ public abstract class AbstractAspectJAdvisorFactory implements AspectJAdvisorFac
return null; return null;
} }
@Nullable
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) { private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor); A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) { if (result != null) {

View File

@ -24,6 +24,7 @@ import org.aopalliance.aop.Advice;
import org.springframework.aop.Advisor; import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut; import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.framework.AopConfigException; import org.springframework.aop.framework.AopConfigException;
import org.springframework.lang.Nullable;
/** /**
* Interface for factories that can create Spring AOP Advisors from classes * Interface for factories that can create Spring AOP Advisors from classes
@ -79,6 +80,7 @@ public interface AspectJAdvisorFactory {
* or if it is a pointcut that will be used by other advice but will not * or if it is a pointcut that will be used by other advice but will not
* create a Spring advice in its own right * create a Spring advice in its own right
*/ */
@Nullable
Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrder, String aspectName); int declarationOrder, String aspectName);
@ -98,6 +100,7 @@ public interface AspectJAdvisorFactory {
* @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice * @see org.springframework.aop.aspectj.AspectJAfterReturningAdvice
* @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice * @see org.springframework.aop.aspectj.AspectJAfterThrowingAdvice
*/ */
@Nullable
Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut, Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName); MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);

View File

@ -17,6 +17,7 @@
package org.springframework.aop.aspectj.annotation; package org.springframework.aop.aspectj.annotation;
import org.springframework.aop.aspectj.AspectInstanceFactory; import org.springframework.aop.aspectj.AspectInstanceFactory;
import org.springframework.lang.Nullable;
/** /**
* Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory} * Subinterface of {@link org.springframework.aop.aspectj.AspectInstanceFactory}
@ -44,6 +45,7 @@ public interface MetadataAwareAspectInstanceFactory extends AspectInstanceFactor
* @return the mutex object (may be {@code null} for no mutex to use) * @return the mutex object (may be {@code null} for no mutex to use)
* @since 4.3 * @since 4.3
*/ */
@Nullable
Object getAspectCreationMutex(); Object getAspectCreationMutex();
} }

View File

@ -50,6 +50,7 @@ import org.springframework.beans.factory.BeanFactory;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.converter.Converter; import org.springframework.core.convert.converter.Converter;
import org.springframework.core.convert.converter.ConvertingComparator; import org.springframework.core.convert.converter.ConvertingComparator;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.comparator.InstanceComparator; import org.springframework.util.comparator.InstanceComparator;
@ -113,7 +114,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
* @see AspectJExpressionPointcut#setBeanFactory * @see AspectJExpressionPointcut#setBeanFactory
* @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader() * @see org.springframework.beans.factory.config.ConfigurableBeanFactory#getBeanClassLoader()
*/ */
public ReflectiveAspectJAdvisorFactory(BeanFactory beanFactory) { public ReflectiveAspectJAdvisorFactory(@Nullable BeanFactory beanFactory) {
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
} }
@ -176,6 +177,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
* @param introductionField the field to introspect * @param introductionField the field to introspect
* @return {@code null} if not an Advisor * @return {@code null} if not an Advisor
*/ */
@Nullable
private Advisor getDeclareParentsAdvisor(Field introductionField) { private Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class); DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
if (declareParents == null) { if (declareParents == null) {
@ -208,6 +210,7 @@ public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFacto
this, aspectInstanceFactory, declarationOrderInAspect, aspectName); this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
} }
@Nullable
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) { private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
AspectJAnnotation<?> aspectJAnnotation = AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod); AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);

View File

@ -3,4 +3,7 @@
* *
* <p>Normally to be used through an AspectJAutoProxyCreator rather than directly. * <p>Normally to be used through an AspectJAutoProxyCreator rather than directly.
*/ */
@NonNullApi
package org.springframework.aop.aspectj.annotation; package org.springframework.aop.aspectj.annotation;
import org.springframework.lang.NonNullApi;

View File

@ -2,4 +2,7 @@
* Base classes enabling auto-proxying based on AspectJ. * Base classes enabling auto-proxying based on AspectJ.
* Support for AspectJ annotation aspects resides in the "aspectj.annotation" package. * Support for AspectJ annotation aspects resides in the "aspectj.annotation" package.
*/ */
@NonNullApi
package org.springframework.aop.aspectj.autoproxy; package org.springframework.aop.aspectj.autoproxy;
import org.springframework.lang.NonNullApi;

View File

@ -8,4 +8,7 @@
* or AspectJ load-time weaver. It is intended to enable the use of a valuable subset of AspectJ * or AspectJ load-time weaver. It is intended to enable the use of a valuable subset of AspectJ
* functionality, with consistent semantics, with the proxy-based Spring AOP framework. * functionality, with consistent semantics, with the proxy-based Spring AOP framework.
*/ */
@NonNullApi
package org.springframework.aop.aspectj; package org.springframework.aop.aspectj;
import org.springframework.lang.NonNullApi;

View File

@ -26,6 +26,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -104,7 +105,7 @@ public abstract class AopConfigUtils {
} }
} }
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) { private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {

View File

@ -45,6 +45,7 @@ import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext; import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils; import org.springframework.util.xml.DomUtils;
@ -466,6 +467,7 @@ class ConfigBeanDefinitionParser implements BeanDefinitionParser {
* {@link org.springframework.beans.factory.config.BeanDefinition} for the pointcut if necessary * {@link org.springframework.beans.factory.config.BeanDefinition} for the pointcut if necessary
* and returns its bean name, otherwise returns the bean name of the referred pointcut. * and returns its bean name, otherwise returns the bean name of the referred pointcut.
*/ */
@Nullable
private Object parsePointcutProperty(Element element, ParserContext parserContext) { private Object parsePointcutProperty(Element element, ParserContext parserContext) {
if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) { if (element.hasAttribute(POINTCUT) && element.hasAttribute(POINTCUT_REF)) {
parserContext.getReaderContext().error( parserContext.getReaderContext().error(

View File

@ -2,4 +2,7 @@
* Support package for declarative AOP configuration, * Support package for declarative AOP configuration,
* with XML schema being the primary configuration format. * with XML schema being the primary configuration format.
*/ */
@NonNullApi
package org.springframework.aop.config; package org.springframework.aop.config;
import org.springframework.lang.NonNullApi;

View File

@ -19,6 +19,8 @@ package org.springframework.aop.framework;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.List; import java.util.List;
import org.springframework.lang.Nullable;
/** /**
* Factory interface for advisor chains. * Factory interface for advisor chains.
* *
@ -36,6 +38,6 @@ public interface AdvisorChainFactory {
* target object, in which case the method's declaring class is the next best option) * target object, in which case the method's declaring class is the next best option)
* @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers) * @return List of MethodInterceptors (may also include InterceptorAndDynamicMethodMatchers)
*/ */
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass); List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
} }

View File

@ -17,6 +17,7 @@
package org.springframework.aop.framework; package org.springframework.aop.framework;
import org.springframework.core.NamedThreadLocal; import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
/** /**
* Class containing static methods used to obtain information about the current AOP invocation. * Class containing static methods used to obtain information about the current AOP invocation.
@ -74,7 +75,8 @@ public abstract class AopContext {
* @return the old proxy, which may be {@code null} if none was bound * @return the old proxy, which may be {@code null} if none was bound
* @see #currentProxy() * @see #currentProxy()
*/ */
static Object setCurrentProxy(Object proxy) { @Nullable
static Object setCurrentProxy(@Nullable Object proxy) {
Object old = currentProxy.get(); Object old = currentProxy.get();
if (proxy != null) { if (proxy != null) {
currentProxy.set(proxy); currentProxy.set(proxy);

View File

@ -16,6 +16,8 @@
package org.springframework.aop.framework; package org.springframework.aop.framework;
import org.springframework.lang.Nullable;
/** /**
* Delegate interface for a configured AOP proxy, allowing for the creation * Delegate interface for a configured AOP proxy, allowing for the creation
* of actual proxy objects. * of actual proxy objects.
@ -48,6 +50,6 @@ public interface AopProxy {
* (or {@code null} for the low-level proxy facility's default) * (or {@code null} for the low-level proxy facility's default)
* @return the new proxy object (never {@code null}) * @return the new proxy object (never {@code null})
*/ */
Object getProxy(ClassLoader classLoader); Object getProxy(@Nullable ClassLoader classLoader);
} }

View File

@ -27,6 +27,7 @@ import org.springframework.aop.TargetSource;
import org.springframework.aop.support.AopUtils; import org.springframework.aop.support.AopUtils;
import org.springframework.aop.target.SingletonTargetSource; import org.springframework.aop.target.SingletonTargetSource;
import org.springframework.core.DecoratingProxy; import org.springframework.core.DecoratingProxy;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -52,6 +53,7 @@ public abstract class AopProxyUtils {
* @see Advised#getTargetSource() * @see Advised#getTargetSource()
* @see SingletonTargetSource#getTarget() * @see SingletonTargetSource#getTarget()
*/ */
@Nullable
public static Object getSingletonTarget(Object candidate) { public static Object getSingletonTarget(Object candidate) {
if (candidate instanceof Advised) { if (candidate instanceof Advised) {
TargetSource targetSource = ((Advised) candidate).getTargetSource(); TargetSource targetSource = ((Advised) candidate).getTargetSource();

View File

@ -50,6 +50,7 @@ import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.cglib.proxy.NoOp; import org.springframework.cglib.proxy.NoOp;
import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy; import org.springframework.cglib.transform.impl.UndeclaredThrowableStrategy;
import org.springframework.core.SmartClassLoader; import org.springframework.core.SmartClassLoader;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -372,7 +373,8 @@ class CglibAopProxy implements AopProxy, Serializable {
* Process a return value. Wraps a return of {@code this} if necessary to be the * Process a return value. Wraps a return of {@code this} if necessary to be the
* {@code proxy} and also verifies that {@code null} is not returned as a primitive. * {@code proxy} and also verifies that {@code null} is not returned as a primitive.
*/ */
private static Object processReturnType(Object proxy, Object target, Method method, Object retVal) { @Nullable
private static Object processReturnType(Object proxy, Object target, Method method, @Nullable Object retVal) {
// Massage return value if necessary // Massage return value if necessary
if (retVal != null && retVal == target && if (retVal != null && retVal == target &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) { !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {

View File

@ -19,6 +19,7 @@ package org.springframework.aop.framework;
import org.aopalliance.intercept.Interceptor; import org.aopalliance.intercept.Interceptor;
import org.springframework.aop.TargetSource; import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
@ -105,7 +106,7 @@ public class ProxyFactory extends ProxyCreatorSupport {
* (or {@code null} for the low-level proxy facility's default) * (or {@code null} for the low-level proxy facility's default)
* @return the proxy object * @return the proxy object
*/ */
public Object getProxy(ClassLoader classLoader) { public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader); return createAopProxy().getProxy(classLoader);
} }

View File

@ -9,4 +9,7 @@
* *
* <p>These adapters do not depend on any other Spring framework classes to allow such usage. * <p>These adapters do not depend on any other Spring framework classes to allow such usage.
*/ */
@NonNullApi
package org.springframework.aop.framework.adapter; package org.springframework.aop.framework.adapter;
import org.springframework.lang.NonNullApi;

View File

@ -47,6 +47,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor; import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -207,6 +208,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* Return the owning {@link BeanFactory}. * Return the owning {@link BeanFactory}.
* May be {@code null}, as this post-processor doesn't need to belong to a bean factory. * May be {@code null}, as this post-processor doesn't need to belong to a bean factory.
*/ */
@Nullable
protected BeanFactory getBeanFactory() { protected BeanFactory getBeanFactory() {
return this.beanFactory; return this.beanFactory;
} }
@ -400,6 +402,7 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @return a TargetSource for this bean * @return a TargetSource for this bean
* @see #setCustomTargetSourceCreators * @see #setCustomTargetSourceCreators
*/ */
@Nullable
protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) { protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
// We can't create fancy target sources for directly registered singletons. // We can't create fancy target sources for directly registered singletons.
if (this.customTargetSourceCreators != null && if (this.customTargetSourceCreators != null &&
@ -578,7 +581,8 @@ public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
* @see #DO_NOT_PROXY * @see #DO_NOT_PROXY
* @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS * @see #PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS
*/ */
@Nullable
protected abstract Object[] getAdvicesAndAdvisorsForBean( protected abstract Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, TargetSource customTargetSource) throws BeansException; Class<?> beanClass, String beanName, @Nullable TargetSource customTargetSource) throws BeansException;
} }

View File

@ -19,6 +19,7 @@ package org.springframework.aop.framework.autoproxy;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.core.Conventions; import org.springframework.core.Conventions;
import org.springframework.lang.Nullable;
/** /**
* Utilities for auto-proxy aware components. * Utilities for auto-proxy aware components.
@ -79,6 +80,7 @@ public abstract class AutoProxyUtils {
* @since 4.2.3 * @since 4.2.3
* @see org.springframework.beans.factory.BeanFactory#getType(String) * @see org.springframework.beans.factory.BeanFactory#getType(String)
*/ */
@Nullable
public static Class<?> determineTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) { public static Class<?> determineTargetClass(ConfigurableListableBeanFactory beanFactory, String beanName) {
if (beanName == null) { if (beanName == null) {
return null; return null;

View File

@ -17,6 +17,7 @@
package org.springframework.aop.framework.autoproxy; package org.springframework.aop.framework.autoproxy;
import org.springframework.core.NamedThreadLocal; import org.springframework.core.NamedThreadLocal;
import org.springframework.lang.Nullable;
/** /**
* Holder for the current proxy creation context, as exposed by auto-proxy creators * Holder for the current proxy creation context, as exposed by auto-proxy creators
@ -37,6 +38,7 @@ public class ProxyCreationContext {
* Return the name of the currently proxied bean instance. * Return the name of the currently proxied bean instance.
* @return the name of the bean, or {@code null} if none available * @return the name of the bean, or {@code null} if none available
*/ */
@Nullable
public static String getCurrentProxiedBeanName() { public static String getCurrentProxiedBeanName() {
return currentProxiedBeanName.get(); return currentProxiedBeanName.get();
} }
@ -45,7 +47,7 @@ public class ProxyCreationContext {
* Set the name of the currently proxied bean instance. * Set the name of the currently proxied bean instance.
* @param beanName the name of the bean, or {@code null} to reset it * @param beanName the name of the bean, or {@code null} to reset it
*/ */
static void setCurrentProxiedBeanName(String beanName) { static void setCurrentProxiedBeanName(@Nullable String beanName) {
if (beanName != null) { if (beanName != null) {
currentProxiedBeanName.set(beanName); currentProxiedBeanName.set(beanName);
} }

View File

@ -17,6 +17,7 @@
package org.springframework.aop.framework.autoproxy; package org.springframework.aop.framework.autoproxy;
import org.springframework.aop.TargetSource; import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
/** /**
* Implementations can create special target sources, such as pooling target * Implementations can create special target sources, such as pooling target
@ -39,6 +40,7 @@ public interface TargetSourceCreator {
* @return a special TargetSource or {@code null} if this TargetSourceCreator isn't * @return a special TargetSource or {@code null} if this TargetSourceCreator isn't
* interested in the particular bean * interested in the particular bean
*/ */
@Nullable
TargetSource getTargetSource(Class<?> beanClass, String beanName); TargetSource getTargetSource(Class<?> beanClass, String beanName);
} }

View File

@ -9,4 +9,7 @@
* as post-processors beans are only automatically detected in application contexts. * as post-processors beans are only automatically detected in application contexts.
* Post-processors can be explicitly registered on a ConfigurableBeanFactory instead. * Post-processors can be explicitly registered on a ConfigurableBeanFactory instead.
*/ */
@NonNullApi
package org.springframework.aop.framework.autoproxy; package org.springframework.aop.framework.autoproxy;
import org.springframework.lang.NonNullApi;

View File

@ -35,6 +35,7 @@ import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.lang.Nullable;
/** /**
* Convenient superclass for * Convenient superclass for
@ -196,6 +197,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
* @param beanName the name of the bean * @param beanName the name of the bean
* @return the AbstractPrototypeBasedTargetSource, or {@code null} if we don't match this * @return the AbstractPrototypeBasedTargetSource, or {@code null} if we don't match this
*/ */
@Nullable
protected abstract AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource( protected abstract AbstractBeanFactoryBasedTargetSource createBeanFactoryBasedTargetSource(
Class<?> beanClass, String beanName); Class<?> beanClass, String beanName);

View File

@ -1,7 +0,0 @@
<html>
<body>
Generic support classes for target source creation.
</body>
</html>

View File

@ -12,4 +12,7 @@
* or ApplicationContext. However, proxies can be created programmatically using the * or ApplicationContext. However, proxies can be created programmatically using the
* ProxyFactory class. * ProxyFactory class.
*/ */
@NonNullApi
package org.springframework.aop.framework; package org.springframework.aop.framework;
import org.springframework.lang.NonNullApi;

View File

@ -38,6 +38,7 @@ import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.core.task.AsyncTaskExecutor; import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.core.task.TaskExecutor; import org.springframework.core.task.TaskExecutor;
import org.springframework.core.task.support.TaskExecutorAdapter; import org.springframework.core.task.support.TaskExecutorAdapter;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.util.concurrent.ListenableFuture; import org.springframework.util.concurrent.ListenableFuture;
@ -143,6 +144,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* Should preferably return an {@link AsyncListenableTaskExecutor} implementation. * Should preferably return an {@link AsyncListenableTaskExecutor} implementation.
* @return the executor to use (or {@code null}, but just if no default executor is available) * @return the executor to use (or {@code null}, but just if no default executor is available)
*/ */
@Nullable
protected AsyncTaskExecutor determineAsyncExecutor(Method method) { protected AsyncTaskExecutor determineAsyncExecutor(Method method) {
AsyncTaskExecutor executor = this.executors.get(method); AsyncTaskExecutor executor = this.executors.get(method);
if (executor == null) { if (executor == null) {
@ -183,6 +185,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* @see #determineAsyncExecutor(Method) * @see #determineAsyncExecutor(Method)
* @see #findQualifiedExecutor(BeanFactory, String) * @see #findQualifiedExecutor(BeanFactory, String)
*/ */
@Nullable
protected abstract String getExecutorQualifier(Method method); protected abstract String getExecutorQualifier(Method method);
/** /**
@ -192,6 +195,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* @since 4.2.6 * @since 4.2.6
* @see #getExecutorQualifier(Method) * @see #getExecutorQualifier(Method)
*/ */
@Nullable
protected Executor findQualifiedExecutor(BeanFactory beanFactory, String qualifier) { protected Executor findQualifiedExecutor(BeanFactory beanFactory, String qualifier) {
if (beanFactory == null) { if (beanFactory == null) {
throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() + throw new IllegalStateException("BeanFactory must be set on " + getClass().getSimpleName() +
@ -212,6 +216,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* @see #findQualifiedExecutor(BeanFactory, String) * @see #findQualifiedExecutor(BeanFactory, String)
* @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME * @see #DEFAULT_TASK_EXECUTOR_BEAN_NAME
*/ */
@Nullable
protected Executor getDefaultExecutor(BeanFactory beanFactory) { protected Executor getDefaultExecutor(BeanFactory beanFactory) {
if (beanFactory != null) { if (beanFactory != null) {
try { try {
@ -256,6 +261,7 @@ public abstract class AsyncExecutionAspectSupport implements BeanFactoryAware {
* @param returnType the declared return type (potentially a {@link Future} variant) * @param returnType the declared return type (potentially a {@link Future} variant)
* @return the execution result (potentially a corresponding {@link Future} handle) * @return the execution result (potentially a corresponding {@link Future} handle)
*/ */
@Nullable
protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) { protected Object doSubmit(Callable<Object> task, AsyncTaskExecutor executor, Class<?> returnType) {
if (CompletableFuture.class.isAssignableFrom(returnType)) { if (CompletableFuture.class.isAssignableFrom(returnType)) {
return CompletableFuture.supplyAsync(new Supplier<Object>() { return CompletableFuture.supplyAsync(new Supplier<Object>() {

View File

@ -24,6 +24,7 @@ import org.aopalliance.intercept.MethodInvocation;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.springframework.core.Constants; import org.springframework.core.Constants;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.StopWatch; import org.springframework.util.StopWatch;
@ -317,7 +318,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* @return the formatted output to write to the log * @return the formatted output to write to the log
*/ */
protected String replacePlaceholders(String message, MethodInvocation methodInvocation, protected String replacePlaceholders(String message, MethodInvocation methodInvocation,
Object returnValue, Throwable throwable, long invocationTime) { @Nullable Object returnValue, @Nullable Throwable throwable, long invocationTime) {
Matcher matcher = PATTERN.matcher(message); Matcher matcher = PATTERN.matcher(message);
@ -371,7 +372,7 @@ public class CustomizableTraceInterceptor extends AbstractTraceInterceptor {
* @param returnValue the value returned by the method invocation. * @param returnValue the value returned by the method invocation.
*/ */
private void appendReturnValue( private void appendReturnValue(
MethodInvocation methodInvocation, Matcher matcher, StringBuffer output, Object returnValue) { MethodInvocation methodInvocation, Matcher matcher, StringBuffer output, @Nullable Object returnValue) {
if (methodInvocation.getMethod().getReturnType() == void.class) { if (methodInvocation.getMethod().getReturnType() == void.class) {
matcher.appendReplacement(output, "void"); matcher.appendReplacement(output, "void");

View File

@ -3,4 +3,7 @@
* More specific interceptors can be found in corresponding * More specific interceptors can be found in corresponding
* functionality packages, like "transaction" and "orm". * functionality packages, like "transaction" and "orm".
*/ */
@NonNullApi
package org.springframework.aop.interceptor; package org.springframework.aop.interceptor;
import org.springframework.lang.NonNullApi;

View File

@ -17,4 +17,7 @@
* <p>Spring AOP can be used programmatically or (preferably) * <p>Spring AOP can be used programmatically or (preferably)
* integrated with the Spring IoC container. * integrated with the Spring IoC container.
*/ */
@NonNullApi
package org.springframework.aop; package org.springframework.aop;
import org.springframework.lang.NonNullApi;

View File

@ -1,4 +1,7 @@
/** /**
* Support for AOP-based scoping of target objects, with configurable backend. * Support for AOP-based scoping of target objects, with configurable backend.
*/ */
@NonNullApi
package org.springframework.aop.scope; package org.springframework.aop.scope;
import org.springframework.lang.NonNullApi;

View File

@ -24,6 +24,7 @@ import org.aopalliance.aop.Advice;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -66,6 +67,7 @@ public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcu
/** /**
* Return the name of the advice bean that this advisor refers to, if any. * Return the name of the advice bean that this advisor refers to, if any.
*/ */
@Nullable
public String getAdviceBeanName() { public String getAdviceBeanName() {
return this.adviceBeanName; return this.adviceBeanName;
} }

View File

@ -18,6 +18,8 @@ package org.springframework.aop.support;
import java.io.Serializable; import java.io.Serializable;
import org.springframework.lang.Nullable;
/** /**
* Abstract superclass for expression pointcuts, * Abstract superclass for expression pointcuts,
* offering location and expression properties. * offering location and expression properties.
@ -49,6 +51,7 @@ public abstract class AbstractExpressionPointcut implements ExpressionPointcut,
* @return location information as a human-readable String, * @return location information as a human-readable String,
* or {@code null} if none is available * or {@code null} if none is available
*/ */
@Nullable
public String getLocation() { public String getLocation() {
return this.location; return this.location;
} }

View File

@ -36,6 +36,7 @@ import org.springframework.aop.SpringProxy;
import org.springframework.aop.TargetClassAware; import org.springframework.aop.TargetClassAware;
import org.springframework.core.BridgeMethodResolver; import org.springframework.core.BridgeMethodResolver;
import org.springframework.core.MethodIntrospector; import org.springframework.core.MethodIntrospector;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -187,7 +188,7 @@ public abstract class AopUtils {
* {@code targetClass} doesn't implement it or is {@code null} * {@code targetClass} doesn't implement it or is {@code null}
* @see org.springframework.util.ClassUtils#getMostSpecificMethod * @see org.springframework.util.ClassUtils#getMostSpecificMethod
*/ */
public static Method getMostSpecificMethod(Method method, Class<?> targetClass) { public static Method getMostSpecificMethod(Method method, @Nullable Class<?> targetClass) {
Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, targetClass); Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
// If we are dealing with method with generic parameters, find the original method. // If we are dealing with method with generic parameters, find the original method.
return BridgeMethodResolver.findBridgedMethod(resolvedMethod); return BridgeMethodResolver.findBridgedMethod(resolvedMethod);
@ -324,6 +325,7 @@ public abstract class AopUtils {
* @throws Throwable if thrown by the target method * @throws Throwable if thrown by the target method
* @throws org.springframework.aop.AopInvocationException in case of a reflection error * @throws org.springframework.aop.AopInvocationException in case of a reflection error
*/ */
@Nullable
public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args) public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
throws Throwable { throws Throwable {

View File

@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter; import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher; import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut; import org.springframework.aop.Pointcut;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -59,7 +60,7 @@ public class ControlFlowPointcut implements Pointcut, ClassFilter, MethodMatcher
* @param clazz the clazz * @param clazz the clazz
* @param methodName the name of the method (may be {@code null}) * @param methodName the name of the method (may be {@code null})
*/ */
public ControlFlowPointcut(Class<?> clazz, String methodName) { public ControlFlowPointcut(Class<?> clazz, @Nullable String methodName) {
Assert.notNull(clazz, "Class must not be null"); Assert.notNull(clazz, "Class must not be null");
this.clazz = clazz; this.clazz = clazz;
this.methodName = methodName; this.methodName = methodName;

View File

@ -27,6 +27,7 @@ import org.springframework.aop.DynamicIntroductionAdvice;
import org.springframework.aop.IntroductionAdvisor; import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.IntroductionInfo; import org.springframework.aop.IntroductionInfo;
import org.springframework.core.Ordered; import org.springframework.core.Ordered;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
@ -64,7 +65,7 @@ public class DefaultIntroductionAdvisor implements IntroductionAdvisor, ClassFil
* @param introductionInfo the IntroductionInfo that describes * @param introductionInfo the IntroductionInfo that describes
* the interface to introduce (may be {@code null}) * the interface to introduce (may be {@code null})
*/ */
public DefaultIntroductionAdvisor(Advice advice, IntroductionInfo introductionInfo) { public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) {
Assert.notNull(advice, "Advice must not be null"); Assert.notNull(advice, "Advice must not be null");
this.advice = advice; this.advice = advice;
if (introductionInfo != null) { if (introductionInfo != null) {

View File

@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import org.springframework.aop.ClassFilter; import org.springframework.aop.ClassFilter;
import org.springframework.aop.IntroductionAwareMethodMatcher; import org.springframework.aop.IntroductionAwareMethodMatcher;
import org.springframework.aop.MethodMatcher; import org.springframework.aop.MethodMatcher;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -87,7 +88,7 @@ public abstract class MethodMatchers {
* asking is the subject on one or more introductions; {@code false} otherwise * asking is the subject on one or more introductions; {@code false} otherwise
* @return whether or not this method matches statically * @return whether or not this method matches statically
*/ */
public static boolean matches(MethodMatcher mm, Method method, Class<?> targetClass, boolean hasIntroductions) { public static boolean matches(MethodMatcher mm, Method method, @Nullable Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(mm, "MethodMatcher must not be null"); Assert.notNull(mm, "MethodMatcher must not be null");
return ((mm instanceof IntroductionAwareMethodMatcher && return ((mm instanceof IntroductionAwareMethodMatcher &&
((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, hasIntroductions)) || ((IntroductionAwareMethodMatcher) mm).matches(method, targetClass, hasIntroductions)) ||

View File

@ -21,6 +21,7 @@ import java.io.Serializable;
import org.aopalliance.aop.Advice; import org.aopalliance.aop.Advice;
import org.springframework.aop.Pointcut; import org.springframework.aop.Pointcut;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
@ -132,6 +133,7 @@ public class RegexpMethodPointcutAdvisor extends AbstractGenericPointcutAdvisor
* will be used. * will be used.
* @return the Pointcut instance (never {@code null}) * @return the Pointcut instance (never {@code null})
*/ */
@Nullable
protected AbstractRegexpMethodPointcut createPointcut() { protected AbstractRegexpMethodPointcut createPointcut() {
return new JdkRegexpMethodPointcut(); return new JdkRegexpMethodPointcut();
} }

View File

@ -21,6 +21,7 @@ import java.lang.annotation.Annotation;
import org.springframework.aop.ClassFilter; import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher; import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut; import org.springframework.aop.Pointcut;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -69,7 +70,7 @@ public class AnnotationMatchingPointcut implements Pointcut {
* (can be {@code null}) * (can be {@code null})
*/ */
public AnnotationMatchingPointcut( public AnnotationMatchingPointcut(
Class<? extends Annotation> classAnnotationType, Class<? extends Annotation> methodAnnotationType) { @Nullable Class<? extends Annotation> classAnnotationType, @Nullable Class<? extends Annotation> methodAnnotationType) {
this(classAnnotationType, methodAnnotationType, false); this(classAnnotationType, methodAnnotationType, false);
} }

View File

@ -1,4 +1,7 @@
/** /**
* Annotation support for AOP pointcuts. * Annotation support for AOP pointcuts.
*/ */
@NonNullApi
package org.springframework.aop.support.annotation; package org.springframework.aop.support.annotation;
import org.springframework.lang.NonNullApi;

View File

@ -1,4 +1,7 @@
/** /**
* Convenience classes for using Spring's AOP API. * Convenience classes for using Spring's AOP API.
*/ */
@NonNullApi
package org.springframework.aop.support; package org.springframework.aop.support;
import org.springframework.lang.NonNullApi;

View File

@ -19,6 +19,7 @@ package org.springframework.aop.target;
import java.io.Serializable; import java.io.Serializable;
import org.springframework.aop.TargetSource; import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
@ -50,7 +51,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
* @param targetClass the target Class (may be {@code null}) * @param targetClass the target Class (may be {@code null})
* @see #getTargetClass() * @see #getTargetClass()
*/ */
public static EmptyTargetSource forClass(Class<?> targetClass) { public static EmptyTargetSource forClass(@Nullable Class<?> targetClass) {
return forClass(targetClass, true); return forClass(targetClass, true);
} }
@ -60,7 +61,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
* @param isStatic whether the TargetSource should be marked as static * @param isStatic whether the TargetSource should be marked as static
* @see #getTargetClass() * @see #getTargetClass()
*/ */
public static EmptyTargetSource forClass(Class<?> targetClass, boolean isStatic) { public static EmptyTargetSource forClass(@Nullable Class<?> targetClass, boolean isStatic) {
return (targetClass == null && isStatic ? INSTANCE : new EmptyTargetSource(targetClass, isStatic)); return (targetClass == null && isStatic ? INSTANCE : new EmptyTargetSource(targetClass, isStatic));
} }
@ -81,7 +82,7 @@ public class EmptyTargetSource implements TargetSource, Serializable {
* @param targetClass the target class to expose (may be {@code null}) * @param targetClass the target class to expose (may be {@code null})
* @param isStatic whether the TargetSource is marked as static * @param isStatic whether the TargetSource is marked as static
*/ */
private EmptyTargetSource(Class<?> targetClass, boolean isStatic) { private EmptyTargetSource(@Nullable Class<?> targetClass, boolean isStatic) {
this.targetClass = targetClass; this.targetClass = targetClass;
this.isStatic = isStatic; this.isStatic = isStatic;
} }

View File

@ -1,7 +0,0 @@
<html>
<body>
Support for AOP-based refreshing of target objects.
</body>
</html>

View File

@ -40,6 +40,7 @@ import org.springframework.core.ResolvableType;
import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionException;
import org.springframework.core.convert.ConverterNotFoundException; import org.springframework.core.convert.ConverterNotFoundException;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
@ -715,6 +716,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
* or {@code null} if not found * or {@code null} if not found
* @throws BeansException in case of introspection failure * @throws BeansException in case of introspection failure
*/ */
@Nullable
protected PropertyHandler getPropertyHandler(String propertyName) throws BeansException { protected PropertyHandler getPropertyHandler(String propertyName) throws BeansException {
Assert.notNull(propertyName, "Property name must not be null"); Assert.notNull(propertyName, "Property name must not be null");
AbstractNestablePropertyAccessor nestedPa = getPropertyAccessorForPropertyPath(propertyName); AbstractNestablePropertyAccessor nestedPa = getPropertyAccessorForPropertyPath(propertyName);
@ -727,6 +729,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
* @param propertyName the name of a local property * @param propertyName the name of a local property
* @return the handler for that property or {@code null} if it has not been found * @return the handler for that property or {@code null} if it has not been found
*/ */
@Nullable
protected abstract PropertyHandler getLocalPropertyHandler(String propertyName); protected abstract PropertyHandler getLocalPropertyHandler(String propertyName);
/** /**
@ -1016,6 +1019,7 @@ public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyA
public abstract TypeDescriptor nested(int level); public abstract TypeDescriptor nested(int level);
@Nullable
public abstract Object getValue() throws Exception; public abstract Object getValue() throws Exception;
public abstract void setValue(Object object, Object value) throws Exception; public abstract void setValue(Object object, Object value) throws Exception;

View File

@ -19,6 +19,8 @@ package org.springframework.beans;
import java.beans.BeanInfo; import java.beans.BeanInfo;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import org.springframework.lang.Nullable;
/** /**
* Strategy interface for creating {@link BeanInfo} instances for Spring beans. * Strategy interface for creating {@link BeanInfo} instances for Spring beans.
* Can be used to plug in custom bean property resolution strategies (e.g. for other * Can be used to plug in custom bean property resolution strategies (e.g. for other
@ -52,6 +54,7 @@ public interface BeanInfoFactory {
* @return the BeanInfo, or {@code null} if the given class is not supported * @return the BeanInfo, or {@code null} if the given class is not supported
* @throws IntrospectionException in case of exceptions * @throws IntrospectionException in case of exceptions
*/ */
@Nullable
BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException; BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException;
} }

View File

@ -19,6 +19,8 @@ package org.springframework.beans;
import java.lang.reflect.Constructor; import java.lang.reflect.Constructor;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import org.springframework.lang.Nullable;
/** /**
* Exception thrown when instantiation of a bean failed. * Exception thrown when instantiation of a bean failed.
* Carries the offending bean class. * Carries the offending bean class.
@ -98,6 +100,7 @@ public class BeanInstantiationException extends FatalBeanException {
* factory method or in case of default instantiation * factory method or in case of default instantiation
* @since 4.3 * @since 4.3
*/ */
@Nullable
public Constructor<?> getConstructor() { public Constructor<?> getConstructor() {
return this.constructor; return this.constructor;
} }
@ -108,6 +111,7 @@ public class BeanInstantiationException extends FatalBeanException {
* or {@code null} in case of constructor-based instantiation * or {@code null} in case of constructor-based instantiation
* @since 4.3 * @since 4.3
*/ */
@Nullable
public Method getConstructingMethod() { public Method getConstructingMethod() {
return this.constructingMethod; return this.constructingMethod;
} }

View File

@ -17,6 +17,7 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.core.AttributeAccessorSupport; import org.springframework.core.AttributeAccessorSupport;
import org.springframework.lang.Nullable;
/** /**
* Extension of {@link org.springframework.core.AttributeAccessorSupport}, * Extension of {@link org.springframework.core.AttributeAccessorSupport},
@ -60,6 +61,7 @@ public class BeanMetadataAttributeAccessor extends AttributeAccessorSupport impl
* @return the corresponding BeanMetadataAttribute object, * @return the corresponding BeanMetadataAttribute object,
* or {@code null} if no such attribute defined * or {@code null} if no such attribute defined
*/ */
@Nullable
public BeanMetadataAttribute getMetadataAttribute(String name) { public BeanMetadataAttribute getMetadataAttribute(String name) {
return (BeanMetadataAttribute) super.getAttribute(name); return (BeanMetadataAttribute) super.getAttribute(name);
} }

View File

@ -16,6 +16,8 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.lang.Nullable;
/** /**
* Interface to be implemented by bean metadata elements * Interface to be implemented by bean metadata elements
* that carry a configuration source object. * that carry a configuration source object.
@ -29,6 +31,7 @@ public interface BeanMetadataElement {
* Return the configuration source {@code Object} for this metadata element * Return the configuration source {@code Object} for this metadata element
* (may be {@code null}). * (may be {@code null}).
*/ */
@Nullable
Object getSource(); Object getSource();
} }

View File

@ -35,6 +35,7 @@ import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ConcurrentReferenceHashMap;
@ -172,6 +173,7 @@ public abstract class BeanUtils {
* @see Class#getMethod * @see Class#getMethod
* @see #findDeclaredMethod * @see #findDeclaredMethod
*/ */
@Nullable
public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) { public static Method findMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
try { try {
return clazz.getMethod(methodName, paramTypes); return clazz.getMethod(methodName, paramTypes);
@ -192,6 +194,7 @@ public abstract class BeanUtils {
* @return the Method object, or {@code null} if not found * @return the Method object, or {@code null} if not found
* @see Class#getDeclaredMethod * @see Class#getDeclaredMethod
*/ */
@Nullable
public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) { public static Method findDeclaredMethod(Class<?> clazz, String methodName, Class<?>... paramTypes) {
try { try {
return clazz.getDeclaredMethod(methodName, paramTypes); return clazz.getDeclaredMethod(methodName, paramTypes);
@ -219,6 +222,7 @@ public abstract class BeanUtils {
* @see Class#getMethods * @see Class#getMethods
* @see #findDeclaredMethodWithMinimalParameters * @see #findDeclaredMethodWithMinimalParameters
*/ */
@Nullable
public static Method findMethodWithMinimalParameters(Class<?> clazz, String methodName) public static Method findMethodWithMinimalParameters(Class<?> clazz, String methodName)
throws IllegalArgumentException { throws IllegalArgumentException {
@ -241,6 +245,7 @@ public abstract class BeanUtils {
* could not be resolved to a unique method with minimal parameters * could not be resolved to a unique method with minimal parameters
* @see Class#getDeclaredMethods * @see Class#getDeclaredMethods
*/ */
@Nullable
public static Method findDeclaredMethodWithMinimalParameters(Class<?> clazz, String methodName) public static Method findDeclaredMethodWithMinimalParameters(Class<?> clazz, String methodName)
throws IllegalArgumentException { throws IllegalArgumentException {
@ -260,6 +265,7 @@ public abstract class BeanUtils {
* @throws IllegalArgumentException if methods of the given name were found but * @throws IllegalArgumentException if methods of the given name were found but
* could not be resolved to a unique method with minimal parameters * could not be resolved to a unique method with minimal parameters
*/ */
@Nullable
public static Method findMethodWithMinimalParameters(Method[] methods, String methodName) public static Method findMethodWithMinimalParameters(Method[] methods, String methodName)
throws IllegalArgumentException { throws IllegalArgumentException {
@ -311,6 +317,7 @@ public abstract class BeanUtils {
* @see #findMethod * @see #findMethod
* @see #findMethodWithMinimalParameters * @see #findMethodWithMinimalParameters
*/ */
@Nullable
public static Method resolveSignature(String signature, Class<?> clazz) { public static Method resolveSignature(String signature, Class<?> clazz) {
Assert.hasText(signature, "'signature' must not be empty"); Assert.hasText(signature, "'signature' must not be empty");
Assert.notNull(clazz, "Class must not be null"); Assert.notNull(clazz, "Class must not be null");
@ -365,6 +372,7 @@ public abstract class BeanUtils {
* @return the corresponding PropertyDescriptor, or {@code null} if none * @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails * @throws BeansException if PropertyDescriptor lookup fails
*/ */
@Nullable
public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName) public static PropertyDescriptor getPropertyDescriptor(Class<?> clazz, String propertyName)
throws BeansException { throws BeansException {
@ -381,6 +389,7 @@ public abstract class BeanUtils {
* @return the corresponding PropertyDescriptor, or {@code null} if none * @return the corresponding PropertyDescriptor, or {@code null} if none
* @throws BeansException if PropertyDescriptor lookup fails * @throws BeansException if PropertyDescriptor lookup fails
*/ */
@Nullable
public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException { public static PropertyDescriptor findPropertyForMethod(Method method) throws BeansException {
return findPropertyForMethod(method, method.getDeclaringClass()); return findPropertyForMethod(method, method.getDeclaringClass());
} }
@ -395,6 +404,7 @@ public abstract class BeanUtils {
* @throws BeansException if PropertyDescriptor lookup fails * @throws BeansException if PropertyDescriptor lookup fails
* @since 3.2.13 * @since 3.2.13
*/ */
@Nullable
public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException { public static PropertyDescriptor findPropertyForMethod(Method method, Class<?> clazz) throws BeansException {
Assert.notNull(method, "Method must not be null"); Assert.notNull(method, "Method must not be null");
PropertyDescriptor[] pds = getPropertyDescriptors(clazz); PropertyDescriptor[] pds = getPropertyDescriptors(clazz);
@ -415,6 +425,7 @@ public abstract class BeanUtils {
* @param targetType the type to find an editor for * @param targetType the type to find an editor for
* @return the corresponding editor, or {@code null} if none found * @return the corresponding editor, or {@code null} if none found
*/ */
@Nullable
public static PropertyEditor findEditorByConvention(Class<?> targetType) { public static PropertyEditor findEditorByConvention(Class<?> targetType) {
if (targetType == null || targetType.isArray() || unknownEditorTypes.contains(targetType)) { if (targetType == null || targetType.isArray() || unknownEditorTypes.contains(targetType)) {
return null; return null;

View File

@ -18,6 +18,8 @@ package org.springframework.beans;
import java.beans.PropertyDescriptor; import java.beans.PropertyDescriptor;
import org.springframework.lang.Nullable;
/** /**
* The central interface of Spring's low-level JavaBeans infrastructure. * The central interface of Spring's low-level JavaBeans infrastructure.
* *
@ -65,6 +67,7 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
* Return the bean instance wrapped by this object, if any. * Return the bean instance wrapped by this object, if any.
* @return the bean instance, or {@code null} if none set * @return the bean instance, or {@code null} if none set
*/ */
@Nullable
Object getWrappedInstance(); Object getWrappedInstance();
/** /**
@ -72,6 +75,7 @@ public interface BeanWrapper extends ConfigurablePropertyAccessor {
* @return the type of the wrapped bean instance, * @return the type of the wrapped bean instance,
* or {@code null} if no wrapped object has been set * or {@code null} if no wrapped object has been set
*/ */
@Nullable
Class<?> getWrappedClass(); Class<?> getWrappedClass();
/** /**

View File

@ -17,6 +17,7 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.lang.Nullable;
/** /**
* Interface that encapsulates configuration methods for a PropertyAccessor. * Interface that encapsulates configuration methods for a PropertyAccessor.
@ -41,6 +42,7 @@ public interface ConfigurablePropertyAccessor extends PropertyAccessor, Property
/** /**
* Return the associated ConversionService, if any. * Return the associated ConversionService, if any.
*/ */
@Nullable
ConversionService getConversionService(); ConversionService getConversionService();
/** /**

View File

@ -18,6 +18,8 @@ package org.springframework.beans;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import org.springframework.lang.Nullable;
/** /**
* Exception thrown when no suitable editor or converter can be found for a bean property. * Exception thrown when no suitable editor or converter can be found for a bean property.
* *
@ -35,7 +37,7 @@ public class ConversionNotSupportedException extends TypeMismatchException {
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public ConversionNotSupportedException(PropertyChangeEvent propertyChangeEvent, public ConversionNotSupportedException(PropertyChangeEvent propertyChangeEvent,
Class<?> requiredType, Throwable cause) { @Nullable Class<?> requiredType, @Nullable Throwable cause) {
super(propertyChangeEvent, requiredType, cause); super(propertyChangeEvent, requiredType, cause);
} }
@ -45,7 +47,7 @@ public class ConversionNotSupportedException extends TypeMismatchException {
* @param requiredType the required target type (or {@code null} if not known) * @param requiredType the required target type (or {@code null} if not known)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public ConversionNotSupportedException(Object value, Class<?> requiredType, Throwable cause) { public ConversionNotSupportedException(@Nullable Object value, @Nullable Class<?> requiredType, @Nullable Throwable cause) {
super(value, requiredType, cause); super(value, requiredType, cause);
} }

View File

@ -37,6 +37,7 @@ import java.util.TreeSet;
import org.apache.commons.logging.Log; import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
/** /**
@ -188,6 +189,7 @@ class ExtendedBeanInfo implements BeanInfo {
} }
} }
@Nullable
private PropertyDescriptor findExistingPropertyDescriptor(String propertyName, Class<?> propertyType) { private PropertyDescriptor findExistingPropertyDescriptor(String propertyName, Class<?> propertyType) {
for (PropertyDescriptor pd : this.propertyDescriptors) { for (PropertyDescriptor pd : this.propertyDescriptors) {
final Class<?> candidateType; final Class<?> candidateType;

View File

@ -16,6 +16,8 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.lang.Nullable;
/** /**
* Interface representing an object whose value set can be merged with * Interface representing an object whose value set can be merged with
* that of a parent object. * that of a parent object.
@ -44,6 +46,6 @@ public interface Mergeable {
* @exception IllegalStateException if merging is not enabled for this instance * @exception IllegalStateException if merging is not enabled for this instance
* (i.e. {@code mergeEnabled} equals {@code false}). * (i.e. {@code mergeEnabled} equals {@code false}).
*/ */
Object merge(Object parent); Object merge(@Nullable Object parent);
} }

View File

@ -23,6 +23,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -267,6 +268,7 @@ public class MutablePropertyValues implements PropertyValues, Serializable {
* @see #getPropertyValue(String) * @see #getPropertyValue(String)
* @see PropertyValue#getValue() * @see PropertyValue#getValue()
*/ */
@Nullable
public Object get(String propertyName) { public Object get(String propertyName) {
PropertyValue pv = getPropertyValue(propertyName); PropertyValue pv = getPropertyValue(propertyName);
return (pv != null ? pv.getValue() : null); return (pv != null ? pv.getValue() : null);

View File

@ -16,6 +16,8 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.lang.Nullable;
/** /**
* Exception thrown on an attempt to set the value of a property that * Exception thrown on an attempt to set the value of a property that
* is not writable (typically because there is no setter method). * is not writable (typically because there is no setter method).
@ -80,6 +82,7 @@ public class NotWritablePropertyException extends InvalidPropertyException {
* Return suggestions for actual bean property names that closely match * Return suggestions for actual bean property names that closely match
* the invalid property name, if any. * the invalid property name, if any.
*/ */
@Nullable
public String[] getPossibleMatches() { public String[] getPossibleMatches() {
return this.possibleMatches; return this.possibleMatches;
} }

View File

@ -18,6 +18,8 @@ package org.springframework.beans;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import org.springframework.lang.Nullable;
/** /**
* Superclass for exceptions related to a property access, * Superclass for exceptions related to a property access,
* such as type mismatch or invocation target exception. * such as type mismatch or invocation target exception.
@ -57,6 +59,7 @@ public abstract class PropertyAccessException extends BeansException {
* <p>May be {@code null}; only available if an actual bean property * <p>May be {@code null}; only available if an actual bean property
* was affected. * was affected.
*/ */
@Nullable
public PropertyChangeEvent getPropertyChangeEvent() { public PropertyChangeEvent getPropertyChangeEvent() {
return this.propertyChangeEvent; return this.propertyChangeEvent;
} }
@ -71,6 +74,7 @@ public abstract class PropertyAccessException extends BeansException {
/** /**
* Return the affected value that was about to be set, if any. * Return the affected value that was about to be set, if any.
*/ */
@Nullable
public Object getValue() { public Object getValue() {
return (this.propertyChangeEvent != null ? this.propertyChangeEvent.getNewValue() : null); return (this.propertyChangeEvent != null ? this.propertyChangeEvent.getNewValue() : null);
} }

View File

@ -19,6 +19,7 @@ package org.springframework.beans;
import java.util.Map; import java.util.Map;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
/** /**
* Common interface for classes that can access named properties * Common interface for classes that can access named properties
@ -86,6 +87,7 @@ public interface PropertyAccessor {
* @throws PropertyAccessException if the property was valid but the * @throws PropertyAccessException if the property was valid but the
* accessor method failed * accessor method failed
*/ */
@Nullable
Class<?> getPropertyType(String propertyName) throws BeansException; Class<?> getPropertyType(String propertyName) throws BeansException;
/** /**
@ -98,6 +100,7 @@ public interface PropertyAccessor {
* @throws InvalidPropertyException if there is no such property or * @throws InvalidPropertyException if there is no such property or
* if the property isn't readable * if the property isn't readable
*/ */
@Nullable
TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException; TypeDescriptor getPropertyTypeDescriptor(String propertyName) throws BeansException;
/** /**

View File

@ -19,6 +19,7 @@ package org.springframework.beans;
import java.io.PrintStream; import java.io.PrintStream;
import java.io.PrintWriter; import java.io.PrintWriter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -71,6 +72,7 @@ public class PropertyBatchUpdateException extends BeansException {
/** /**
* Return the exception for this field, or {@code null} if there isn't any. * Return the exception for this field, or {@code null} if there isn't any.
*/ */
@Nullable
public PropertyAccessException getPropertyAccessException(String propertyName) { public PropertyAccessException getPropertyAccessException(String propertyName) {
for (PropertyAccessException pae : this.propertyAccessExceptions) { for (PropertyAccessException pae : this.propertyAccessExceptions) {
if (ObjectUtils.nullSafeEquals(propertyName, pae.getPropertyName())) { if (ObjectUtils.nullSafeEquals(propertyName, pae.getPropertyName())) {

View File

@ -18,6 +18,8 @@ package org.springframework.beans;
import java.beans.PropertyEditor; import java.beans.PropertyEditor;
import org.springframework.lang.Nullable;
/** /**
* Encapsulates methods for registering JavaBeans {@link PropertyEditor PropertyEditors}. * Encapsulates methods for registering JavaBeans {@link PropertyEditor PropertyEditors}.
* This is the central interface that a {@link PropertyEditorRegistrar} operates on. * This is the central interface that a {@link PropertyEditorRegistrar} operates on.
@ -64,7 +66,7 @@ public interface PropertyEditorRegistry {
* {@code null} if registering an editor for all properties of the given type * {@code null} if registering an editor for all properties of the given type
* @param propertyEditor editor to register * @param propertyEditor editor to register
*/ */
void registerCustomEditor(Class<?> requiredType, String propertyPath, PropertyEditor propertyEditor); void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor);
/** /**
* Find a custom property editor for the given type and property. * Find a custom property editor for the given type and property.
@ -74,6 +76,7 @@ public interface PropertyEditorRegistry {
* {@code null} if looking for an editor for all properties of the given type * {@code null} if looking for an editor for all properties of the given type
* @return the registered editor, or {@code null} if none * @return the registered editor, or {@code null} if none
*/ */
PropertyEditor findCustomEditor(Class<?> requiredType, String propertyPath); @Nullable
PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath);
} }

View File

@ -74,6 +74,7 @@ import org.springframework.beans.propertyeditors.ZoneIdEditor;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.support.ResourceArrayPropertyEditor; import org.springframework.core.io.support.ResourceArrayPropertyEditor;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
@ -118,6 +119,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
/** /**
* Return the associated ConversionService, if any. * Return the associated ConversionService, if any.
*/ */
@Nullable
public ConversionService getConversionService() { public ConversionService getConversionService() {
return this.conversionService; return this.conversionService;
} }
@ -169,6 +171,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @return the default editor, or {@code null} if none found * @return the default editor, or {@code null} if none found
* @see #registerDefaultEditors * @see #registerDefaultEditors
*/ */
@Nullable
public PropertyEditor getDefaultEditor(Class<?> requiredType) { public PropertyEditor getDefaultEditor(Class<?> requiredType) {
if (!this.defaultEditorsActive) { if (!this.defaultEditorsActive) {
return null; return null;
@ -336,7 +339,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* can be {@code null} if not known) * can be {@code null} if not known)
* @return whether a matching custom editor has been found * @return whether a matching custom editor has been found
*/ */
public boolean hasCustomEditorForElement(Class<?> elementType, String propertyPath) { public boolean hasCustomEditorForElement(@Nullable Class<?> elementType, @Nullable String propertyPath) {
if (propertyPath != null && this.customEditorsForPath != null) { if (propertyPath != null && this.customEditorsForPath != null) {
for (Map.Entry<String, CustomEditorHolder> entry : this.customEditorsForPath.entrySet()) { for (Map.Entry<String, CustomEditorHolder> entry : this.customEditorsForPath.entrySet()) {
if (PropertyAccessorUtils.matchesProperty(entry.getKey(), propertyPath)) { if (PropertyAccessorUtils.matchesProperty(entry.getKey(), propertyPath)) {
@ -361,6 +364,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @return the type of the property, or {@code null} if not determinable * @return the type of the property, or {@code null} if not determinable
* @see BeanWrapper#getPropertyType(String) * @see BeanWrapper#getPropertyType(String)
*/ */
@Nullable
protected Class<?> getPropertyType(String propertyPath) { protected Class<?> getPropertyType(String propertyPath) {
return null; return null;
} }
@ -371,6 +375,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @param requiredType the type to look for * @param requiredType the type to look for
* @return the custom editor, or {@code null} if none specific for this property * @return the custom editor, or {@code null} if none specific for this property
*/ */
@Nullable
private PropertyEditor getCustomEditor(String propertyName, Class<?> requiredType) { private PropertyEditor getCustomEditor(String propertyName, Class<?> requiredType) {
CustomEditorHolder holder = this.customEditorsForPath.get(propertyName); CustomEditorHolder holder = this.customEditorsForPath.get(propertyName);
return (holder != null ? holder.getPropertyEditor(requiredType) : null); return (holder != null ? holder.getPropertyEditor(requiredType) : null);
@ -384,6 +389,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @return the custom editor, or {@code null} if none found for this type * @return the custom editor, or {@code null} if none found for this type
* @see java.beans.PropertyEditor#getAsText() * @see java.beans.PropertyEditor#getAsText()
*/ */
@Nullable
private PropertyEditor getCustomEditor(Class<?> requiredType) { private PropertyEditor getCustomEditor(Class<?> requiredType) {
if (requiredType == null || this.customEditors == null) { if (requiredType == null || this.customEditors == null) {
return null; return null;
@ -420,6 +426,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* @param propertyName the name of the property * @param propertyName the name of the property
* @return the property type, or {@code null} if not determinable * @return the property type, or {@code null} if not determinable
*/ */
@Nullable
protected Class<?> guessPropertyTypeFromEditors(String propertyName) { protected Class<?> guessPropertyTypeFromEditors(String propertyName) {
if (this.customEditorsForPath != null) { if (this.customEditorsForPath != null) {
CustomEditorHolder editorHolder = this.customEditorsForPath.get(propertyName); CustomEditorHolder editorHolder = this.customEditorsForPath.get(propertyName);
@ -445,7 +452,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
* If this is non-null, only editors registered for a path below this nested property * If this is non-null, only editors registered for a path below this nested property
* will be copied. If this is null, all editors will be copied. * will be copied. If this is null, all editors will be copied.
*/ */
protected void copyCustomEditorsTo(PropertyEditorRegistry target, String nestedProperty) { protected void copyCustomEditorsTo(PropertyEditorRegistry target, @Nullable String nestedProperty) {
String actualPropertyName = String actualPropertyName =
(nestedProperty != null ? PropertyAccessorUtils.getPropertyName(nestedProperty) : null); (nestedProperty != null ? PropertyAccessorUtils.getPropertyName(nestedProperty) : null);
if (this.customEditors != null) { if (this.customEditors != null) {

View File

@ -16,6 +16,8 @@
package org.springframework.beans; package org.springframework.beans;
import org.springframework.lang.Nullable;
/** /**
* Holder containing one or more {@link PropertyValue} objects, * Holder containing one or more {@link PropertyValue} objects,
* typically comprising one update for a specific target bean. * typically comprising one update for a specific target bean.
@ -37,6 +39,7 @@ public interface PropertyValues {
* @param propertyName the name to search for * @param propertyName the name to search for
* @return the property value, or {@code null} * @return the property value, or {@code null}
*/ */
@Nullable
PropertyValue getPropertyValue(String propertyName); PropertyValue getPropertyValue(String propertyName);
/** /**

View File

@ -19,6 +19,7 @@ package org.springframework.beans;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
/** /**
* Interface that defines type conversion methods. Typically (but not necessarily) * Interface that defines type conversion methods. Typically (but not necessarily)
@ -49,7 +50,7 @@ public interface TypeConverter {
* @see org.springframework.core.convert.ConversionService * @see org.springframework.core.convert.ConversionService
* @see org.springframework.core.convert.converter.Converter * @see org.springframework.core.convert.converter.Converter
*/ */
<T> T convertIfNecessary(Object value, Class<T> requiredType) throws TypeMismatchException; <T> T convertIfNecessary(Object value, @Nullable Class<T> requiredType) throws TypeMismatchException;
/** /**
* Convert the value to the required type (if necessary from a String). * Convert the value to the required type (if necessary from a String).
@ -67,7 +68,7 @@ public interface TypeConverter {
* @see org.springframework.core.convert.ConversionService * @see org.springframework.core.convert.ConversionService
* @see org.springframework.core.convert.converter.Converter * @see org.springframework.core.convert.converter.Converter
*/ */
<T> T convertIfNecessary(Object value, Class<T> requiredType, MethodParameter methodParam) <T> T convertIfNecessary(Object value, @Nullable Class<T> requiredType, @Nullable MethodParameter methodParam)
throws TypeMismatchException; throws TypeMismatchException;
/** /**
@ -86,7 +87,7 @@ public interface TypeConverter {
* @see org.springframework.core.convert.ConversionService * @see org.springframework.core.convert.ConversionService
* @see org.springframework.core.convert.converter.Converter * @see org.springframework.core.convert.converter.Converter
*/ */
<T> T convertIfNecessary(Object value, Class<T> requiredType, Field field) <T> T convertIfNecessary(Object value, @Nullable Class<T> requiredType, @Nullable Field field)
throws TypeMismatchException; throws TypeMismatchException;
} }

View File

@ -34,6 +34,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.convert.ConversionFailedException; import org.springframework.core.convert.ConversionFailedException;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.TypeDescriptor; import org.springframework.core.convert.TypeDescriptor;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.NumberUtils; import org.springframework.util.NumberUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -90,7 +91,7 @@ class TypeConverterDelegate {
* @return the new value, possibly the result of type conversion * @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed * @throws IllegalArgumentException if type conversion failed
*/ */
public <T> T convertIfNecessary(Object newValue, Class<T> requiredType, MethodParameter methodParam) public <T> T convertIfNecessary(Object newValue, @Nullable Class<T> requiredType, @Nullable MethodParameter methodParam)
throws IllegalArgumentException { throws IllegalArgumentException {
return convertIfNecessary(null, null, newValue, requiredType, return convertIfNecessary(null, null, newValue, requiredType,
@ -107,7 +108,7 @@ class TypeConverterDelegate {
* @return the new value, possibly the result of type conversion * @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed * @throws IllegalArgumentException if type conversion failed
*/ */
public <T> T convertIfNecessary(Object newValue, Class<T> requiredType, Field field) public <T> T convertIfNecessary(Object newValue, @Nullable Class<T> requiredType, @Nullable Field field)
throws IllegalArgumentException { throws IllegalArgumentException {
return convertIfNecessary(null, null, newValue, requiredType, return convertIfNecessary(null, null, newValue, requiredType,
@ -125,7 +126,7 @@ class TypeConverterDelegate {
* @throws IllegalArgumentException if type conversion failed * @throws IllegalArgumentException if type conversion failed
*/ */
public <T> T convertIfNecessary( public <T> T convertIfNecessary(
String propertyName, Object oldValue, Object newValue, Class<T> requiredType) String propertyName, @Nullable Object oldValue, Object newValue, @Nullable Class<T> requiredType)
throws IllegalArgumentException { throws IllegalArgumentException {
return convertIfNecessary(propertyName, oldValue, newValue, requiredType, TypeDescriptor.valueOf(requiredType)); return convertIfNecessary(propertyName, oldValue, newValue, requiredType, TypeDescriptor.valueOf(requiredType));
@ -144,8 +145,8 @@ class TypeConverterDelegate {
* @throws IllegalArgumentException if type conversion failed * @throws IllegalArgumentException if type conversion failed
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue, public <T> T convertIfNecessary(String propertyName, @Nullable Object oldValue, Object newValue,
Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException { @Nullable Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException {
// Custom editor for this type? // Custom editor for this type?
PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName); PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName);
@ -357,6 +358,7 @@ class TypeConverterDelegate {
* @param requiredType the type to find an editor for * @param requiredType the type to find an editor for
* @return the corresponding editor, or {@code null} if none * @return the corresponding editor, or {@code null} if none
*/ */
@Nullable
private PropertyEditor findDefaultEditor(Class<?> requiredType) { private PropertyEditor findDefaultEditor(Class<?> requiredType) {
PropertyEditor editor = null; PropertyEditor editor = null;
if (requiredType != null) { if (requiredType != null) {
@ -381,7 +383,7 @@ class TypeConverterDelegate {
* @return the new value, possibly the result of type conversion * @return the new value, possibly the result of type conversion
* @throws IllegalArgumentException if type conversion failed * @throws IllegalArgumentException if type conversion failed
*/ */
private Object doConvertValue(Object oldValue, Object newValue, Class<?> requiredType, PropertyEditor editor) { private Object doConvertValue(@Nullable Object oldValue, Object newValue, @Nullable Class<?> requiredType, PropertyEditor editor) {
Object convertedValue = newValue; Object convertedValue = newValue;
if (editor != null && !(convertedValue instanceof String)) { if (editor != null && !(convertedValue instanceof String)) {
@ -443,7 +445,7 @@ class TypeConverterDelegate {
* @param editor the PropertyEditor to use * @param editor the PropertyEditor to use
* @return the converted value * @return the converted value
*/ */
private Object doConvertTextValue(Object oldValue, String newTextValue, PropertyEditor editor) { private Object doConvertTextValue(@Nullable Object oldValue, String newTextValue, PropertyEditor editor) {
try { try {
editor.setValue(oldValue); editor.setValue(oldValue);
} }

View File

@ -18,6 +18,7 @@ package org.springframework.beans;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
/** /**
@ -55,7 +56,7 @@ public class TypeMismatchException extends PropertyAccessException {
* @param requiredType the required target type (or {@code null} if not known) * @param requiredType the required target type (or {@code null} if not known)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public TypeMismatchException(PropertyChangeEvent propertyChangeEvent, Class<?> requiredType, Throwable cause) { public TypeMismatchException(PropertyChangeEvent propertyChangeEvent, @Nullable Class<?> requiredType, @Nullable Throwable cause) {
super(propertyChangeEvent, super(propertyChangeEvent,
"Failed to convert property value of type '" + "Failed to convert property value of type '" +
ClassUtils.getDescriptiveType(propertyChangeEvent.getNewValue()) + "'" + ClassUtils.getDescriptiveType(propertyChangeEvent.getNewValue()) + "'" +
@ -73,7 +74,7 @@ public class TypeMismatchException extends PropertyAccessException {
* @param value the offending value that couldn't be converted (may be {@code null}) * @param value the offending value that couldn't be converted (may be {@code null})
* @param requiredType the required target type (or {@code null} if not known) * @param requiredType the required target type (or {@code null} if not known)
*/ */
public TypeMismatchException(Object value, Class<?> requiredType) { public TypeMismatchException(@Nullable Object value, @Nullable Class<?> requiredType) {
this(value, requiredType, null); this(value, requiredType, null);
} }
@ -83,7 +84,7 @@ public class TypeMismatchException extends PropertyAccessException {
* @param requiredType the required target type (or {@code null} if not known) * @param requiredType the required target type (or {@code null} if not known)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public TypeMismatchException(Object value, Class<?> requiredType, Throwable cause) { public TypeMismatchException(@Nullable Object value, @Nullable Class<?> requiredType, @Nullable Throwable cause) {
super("Failed to convert value of type '" + ClassUtils.getDescriptiveType(value) + "'" + super("Failed to convert value of type '" + ClassUtils.getDescriptiveType(value) + "'" +
(requiredType != null ? " to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : ""), (requiredType != null ? " to required type '" + ClassUtils.getQualifiedName(requiredType) + "'" : ""),
cause); cause);
@ -103,6 +104,7 @@ public class TypeMismatchException extends PropertyAccessException {
/** /**
* Return the required target type, if any. * Return the required target type, if any.
*/ */
@Nullable
public Class<?> getRequiredType() { public Class<?> getRequiredType() {
return this.requiredType; return this.requiredType;
} }

View File

@ -24,6 +24,7 @@ import java.util.Set;
import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory; import org.springframework.beans.PropertyAccessorFactory;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringValueResolver; import org.springframework.util.StringValueResolver;
@ -44,7 +45,7 @@ public abstract class AnnotationBeanUtils {
* @param excludedProperties the names of excluded properties, if any * @param excludedProperties the names of excluded properties, if any
* @see org.springframework.beans.BeanWrapper * @see org.springframework.beans.BeanWrapper
*/ */
public static void copyPropertiesToBean(Annotation ann, Object bean, String... excludedProperties) { public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable String... excludedProperties) {
copyPropertiesToBean(ann, bean, null, excludedProperties); copyPropertiesToBean(ann, bean, null, excludedProperties);
} }
@ -58,7 +59,7 @@ public abstract class AnnotationBeanUtils {
* @param excludedProperties the names of excluded properties, if any * @param excludedProperties the names of excluded properties, if any
* @see org.springframework.beans.BeanWrapper * @see org.springframework.beans.BeanWrapper
*/ */
public static void copyPropertiesToBean(Annotation ann, Object bean, StringValueResolver valueResolver, String... excludedProperties) { public static void copyPropertiesToBean(Annotation ann, Object bean, @Nullable StringValueResolver valueResolver, @Nullable String... excludedProperties) {
Set<String> excluded = new HashSet<>(Arrays.asList(excludedProperties)); Set<String> excluded = new HashSet<>(Arrays.asList(excludedProperties));
Method[] annotationProperties = ann.annotationType().getDeclaredMethods(); Method[] annotationProperties = ann.annotationType().getDeclaredMethods();
BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(bean);

View File

@ -1,4 +1,7 @@
/** /**
* Support package for beans-style handling of Java 5 annotations. * Support package for beans-style handling of Java 5 annotations.
*/ */
@NonNullApi
package org.springframework.beans.annotation; package org.springframework.beans.annotation;
import org.springframework.lang.NonNullApi;

View File

@ -16,6 +16,8 @@
package org.springframework.beans.factory; package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
/** /**
* Callback that allows a bean to be aware of the bean * Callback that allows a bean to be aware of the bean
* {@link ClassLoader class loader}; that is, the class loader used by the * {@link ClassLoader class loader}; that is, the class loader used by the
@ -50,6 +52,6 @@ public interface BeanClassLoaderAware extends Aware {
* the {@code ClassLoader} obtained via * the {@code ClassLoader} obtained via
* {@link org.springframework.util.ClassUtils#getDefaultClassLoader()} * {@link org.springframework.util.ClassUtils#getDefaultClassLoader()}
*/ */
void setBeanClassLoader(ClassLoader classLoader); void setBeanClassLoader(@Nullable ClassLoader classLoader);
} }

View File

@ -23,6 +23,7 @@ import java.util.List;
import org.springframework.beans.FatalBeanException; import org.springframework.beans.FatalBeanException;
import org.springframework.core.NestedRuntimeException; import org.springframework.core.NestedRuntimeException;
import org.springframework.lang.Nullable;
/** /**
* Exception thrown when a BeanFactory encounters an error when * Exception thrown when a BeanFactory encounters an error when
@ -109,6 +110,7 @@ public class BeanCreationException extends FatalBeanException {
/** /**
* Return the name of the bean requested, if any. * Return the name of the bean requested, if any.
*/ */
@Nullable
public String getBeanName() { public String getBeanName() {
return this.beanName; return this.beanName;
} }
@ -117,6 +119,7 @@ public class BeanCreationException extends FatalBeanException {
* Return the description of the resource that the bean * Return the description of the resource that the bean
* definition came from, if any. * definition came from, if any.
*/ */
@Nullable
public String getResourceDescription() { public String getResourceDescription() {
return this.resourceDescription; return this.resourceDescription;
} }
@ -138,6 +141,7 @@ public class BeanCreationException extends FatalBeanException {
* Return the related causes, if any. * Return the related causes, if any.
* @return the array of related causes, or {@code null} if none * @return the array of related causes, or {@code null} if none
*/ */
@Nullable
public Throwable[] getRelatedCauses() { public Throwable[] getRelatedCauses() {
if (this.relatedCauses == null) { if (this.relatedCauses == null) {
return null; return null;

View File

@ -17,6 +17,7 @@
package org.springframework.beans.factory; package org.springframework.beans.factory;
import org.springframework.beans.FatalBeanException; import org.springframework.beans.FatalBeanException;
import org.springframework.lang.Nullable;
/** /**
* Exception thrown when a BeanFactory encounters an invalid bean definition: * Exception thrown when a BeanFactory encounters an invalid bean definition:
@ -47,7 +48,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
* @param msg the detail message (used as exception message as-is) * @param msg the detail message (used as exception message as-is)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public BeanDefinitionStoreException(String msg, Throwable cause) { public BeanDefinitionStoreException(String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
} }
@ -67,7 +68,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
* @param msg the detail message (used as exception message as-is) * @param msg the detail message (used as exception message as-is)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public BeanDefinitionStoreException(String resourceDescription, String msg, Throwable cause) { public BeanDefinitionStoreException(String resourceDescription, String msg, @Nullable Throwable cause) {
super(msg, cause); super(msg, cause);
this.resourceDescription = resourceDescription; this.resourceDescription = resourceDescription;
} }
@ -91,7 +92,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
* the resource and the name of the bean) * the resource and the name of the bean)
* @param cause the root cause (may be {@code null}) * @param cause the root cause (may be {@code null})
*/ */
public BeanDefinitionStoreException(String resourceDescription, String beanName, String msg, Throwable cause) { public BeanDefinitionStoreException(String resourceDescription, String beanName, String msg, @Nullable Throwable cause) {
super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg, cause); super("Invalid bean definition with name '" + beanName + "' defined in " + resourceDescription + ": " + msg, cause);
this.resourceDescription = resourceDescription; this.resourceDescription = resourceDescription;
this.beanName = beanName; this.beanName = beanName;
@ -102,6 +103,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
* Return the description of the resource that the bean * Return the description of the resource that the bean
* definition came from, if any. * definition came from, if any.
*/ */
@Nullable
public String getResourceDescription() { public String getResourceDescription() {
return this.resourceDescription; return this.resourceDescription;
} }
@ -109,6 +111,7 @@ public class BeanDefinitionStoreException extends FatalBeanException {
/** /**
* Return the name of the bean requested, if any. * Return the name of the bean requested, if any.
*/ */
@Nullable
public String getBeanName() { public String getBeanName() {
return this.beanName; return this.beanName;
} }

View File

@ -18,6 +18,7 @@ package org.springframework.beans.factory;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/** /**
* The root interface for accessing a Spring bean container. * The root interface for accessing a Spring bean container.
@ -156,7 +157,7 @@ public interface BeanFactory {
* @throws BeanNotOfRequiredTypeException if the bean is not of the required type * @throws BeanNotOfRequiredTypeException if the bean is not of the required type
* @throws BeansException if the bean could not be created * @throws BeansException if the bean could not be created
*/ */
<T> T getBean(String name, Class<T> requiredType) throws BeansException; <T> T getBean(String name, @Nullable Class<T> requiredType) throws BeansException;
/** /**
* Return the bean instance that uniquely matches the given object type, if any. * Return the bean instance that uniquely matches the given object type, if any.
@ -313,6 +314,7 @@ public interface BeanFactory {
* @see #getBean * @see #getBean
* @see #isTypeMatch * @see #isTypeMatch
*/ */
@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException;
/** /**

View File

@ -16,6 +16,8 @@
package org.springframework.beans.factory; package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
/** /**
* Interface to be implemented by objects used within a {@link BeanFactory} which * Interface to be implemented by objects used within a {@link BeanFactory} which
* are themselves factories for individual objects. If a bean implements this * are themselves factories for individual objects. If a bean implements this
@ -72,6 +74,7 @@ public interface FactoryBean<T> {
* @throws Exception in case of creation errors * @throws Exception in case of creation errors
* @see FactoryBeanNotInitializedException * @see FactoryBeanNotInitializedException
*/ */
@Nullable
T getObject() throws Exception; T getObject() throws Exception;
/** /**
@ -93,6 +96,7 @@ public interface FactoryBean<T> {
* or {@code null} if not known at the time of the call * or {@code null} if not known at the time of the call
* @see ListableBeanFactory#getBeansOfType * @see ListableBeanFactory#getBeansOfType
*/ */
@Nullable
Class<?> getObjectType(); Class<?> getObjectType();
/** /**

View File

@ -16,6 +16,8 @@
package org.springframework.beans.factory; package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
/** /**
* Sub-interface implemented by bean factories that can be part * Sub-interface implemented by bean factories that can be part
* of a hierarchy. * of a hierarchy.
@ -34,6 +36,7 @@ public interface HierarchicalBeanFactory extends BeanFactory {
/** /**
* Return the parent bean factory, or {@code null} if there is none. * Return the parent bean factory, or {@code null} if there is none.
*/ */
@Nullable
BeanFactory getParentBeanFactory(); BeanFactory getParentBeanFactory();
/** /**

View File

@ -22,6 +22,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Member; import java.lang.reflect.Member;
import org.springframework.core.MethodParameter; import org.springframework.core.MethodParameter;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
/** /**
@ -83,6 +84,7 @@ public class InjectionPoint {
* <p>Note: Either MethodParameter or Field is available. * <p>Note: Either MethodParameter or Field is available.
* @return the MethodParameter, or {@code null} if none * @return the MethodParameter, or {@code null} if none
*/ */
@Nullable
public MethodParameter getMethodParameter() { public MethodParameter getMethodParameter() {
return this.methodParameter; return this.methodParameter;
} }
@ -92,6 +94,7 @@ public class InjectionPoint {
* <p>Note: Either MethodParameter or Field is available. * <p>Note: Either MethodParameter or Field is available.
* @return the Field, or {@code null} if none * @return the Field, or {@code null} if none
*/ */
@Nullable
public Field getField() { public Field getField() {
return this.field; return this.field;
} }
@ -117,6 +120,7 @@ public class InjectionPoint {
* @return the annotation instance, or {@code null} if none found * @return the annotation instance, or {@code null} if none found
* @since 4.3.9 * @since 4.3.9
*/ */
@Nullable
public <A extends Annotation> A getAnnotation(Class<A> annotationType) { public <A extends Annotation> A getAnnotation(Class<A> annotationType) {
return (this.field != null ? this.field.getAnnotation(annotationType) : return (this.field != null ? this.field.getAnnotation(annotationType) :
this.methodParameter.getParameterAnnotation(annotationType)); this.methodParameter.getParameterAnnotation(annotationType));

View File

@ -21,6 +21,7 @@ import java.util.Map;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType; import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
/** /**
* Extension of the {@link BeanFactory} interface to be implemented by bean factories * Extension of the {@link BeanFactory} interface to be implemented by bean factories
@ -113,7 +114,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType * @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, ResolvableType) * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, ResolvableType)
*/ */
String[] getBeanNamesForType(ResolvableType type); String[] getBeanNamesForType(@Nullable ResolvableType type);
/** /**
* Return the names of beans matching the given type (including subclasses), * Return the names of beans matching the given type (including subclasses),
@ -140,7 +141,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType * @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class) * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class)
*/ */
String[] getBeanNamesForType(Class<?> type); String[] getBeanNamesForType(@Nullable Class<?> type);
/** /**
* Return the names of beans matching the given type (including subclasses), * Return the names of beans matching the given type (including subclasses),
@ -173,7 +174,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType * @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean) * @see BeanFactoryUtils#beanNamesForTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/ */
String[] getBeanNamesForType(Class<?> type, boolean includeNonSingletons, boolean allowEagerInit); String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit);
/** /**
* Return the bean instances that match the given object type (including * Return the bean instances that match the given object type (including
@ -203,7 +204,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType * @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class) * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class)
*/ */
<T> Map<String, T> getBeansOfType(Class<T> type) throws BeansException; <T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
/** /**
* Return the bean instances that match the given object type (including * Return the bean instances that match the given object type (including
@ -238,7 +239,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @see FactoryBean#getObjectType * @see FactoryBean#getObjectType
* @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean) * @see BeanFactoryUtils#beansOfTypeIncludingAncestors(ListableBeanFactory, Class, boolean, boolean)
*/ */
<T> Map<String, T> getBeansOfType(Class<T> type, boolean includeNonSingletons, boolean allowEagerInit) <T> Map<String, T> getBeansOfType(@Nullable Class<T> type, boolean includeNonSingletons, boolean allowEagerInit)
throws BeansException; throws BeansException;
/** /**
@ -271,6 +272,7 @@ public interface ListableBeanFactory extends BeanFactory {
* @throws NoSuchBeanDefinitionException if there is no bean with the given name * @throws NoSuchBeanDefinitionException if there is no bean with the given name
* @since 3.0 * @since 3.0
*/ */
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) <A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException; throws NoSuchBeanDefinitionException;

View File

@ -19,6 +19,7 @@ package org.springframework.beans.factory;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collection; import java.util.Collection;
import org.springframework.lang.Nullable;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
/** /**
@ -85,6 +86,7 @@ public class NoUniqueBeanDefinitionException extends NoSuchBeanDefinitionExcepti
* @since 4.3 * @since 4.3
* @see #getBeanType() * @see #getBeanType()
*/ */
@Nullable
public Collection<String> getBeanNamesFound() { public Collection<String> getBeanNamesFound() {
return this.beanNamesFound; return this.beanNamesFound;
} }

View File

@ -19,6 +19,7 @@ package org.springframework.beans.factory;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.springframework.beans.BeansException; import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;
/** /**
* A variant of {@link ObjectFactory} designed specifically for injection points, * A variant of {@link ObjectFactory} designed specifically for injection points,
@ -48,6 +49,7 @@ public interface ObjectProvider<T> extends ObjectFactory<T> {
* @throws BeansException in case of creation errors * @throws BeansException in case of creation errors
* @see #getObject() * @see #getObject()
*/ */
@Nullable
T getIfAvailable() throws BeansException; T getIfAvailable() throws BeansException;
/** /**
@ -74,6 +76,7 @@ public interface ObjectProvider<T> extends ObjectFactory<T> {
* @throws BeansException in case of creation errors * @throws BeansException in case of creation errors
* @see #getObject() * @see #getObject()
*/ */
@Nullable
T getIfUnique() throws BeansException; T getIfUnique() throws BeansException;
/** /**

View File

@ -19,6 +19,7 @@ package org.springframework.beans.factory.annotation;
import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.core.type.AnnotationMetadata; import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.MethodMetadata; import org.springframework.core.type.MethodMetadata;
import org.springframework.lang.Nullable;
/** /**
* Extended {@link org.springframework.beans.factory.config.BeanDefinition} * Extended {@link org.springframework.beans.factory.config.BeanDefinition}
@ -44,6 +45,7 @@ public interface AnnotatedBeanDefinition extends BeanDefinition {
* @return the factory method metadata, or {@code null} if none * @return the factory method metadata, or {@code null} if none
* @since 4.1.1 * @since 4.1.1
*/ */
@Nullable
MethodMetadata getFactoryMethodMetadata(); MethodMetadata getFactoryMethodMetadata();
} }

View File

@ -60,6 +60,7 @@ import org.springframework.core.Ordered;
import org.springframework.core.PriorityOrdered; import org.springframework.core.PriorityOrdered;
import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -468,6 +469,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
return new InjectionMetadata(clazz, elements); return new InjectionMetadata(clazz, elements);
} }
@Nullable
private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) { private AnnotationAttributes findAutowiredAnnotation(AccessibleObject ao) {
if (ao.getAnnotations().length > 0) { if (ao.getAnnotations().length > 0) {
for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) { for (Class<? extends Annotation> type : this.autowiredAnnotationTypes) {
@ -691,6 +693,7 @@ public class AutowiredAnnotationBeanPostProcessor extends InstantiationAwareBean
} }
} }
@Nullable
private Object[] resolveCachedArguments(String beanName) { private Object[] resolveCachedArguments(String beanName) {
if (this.cachedMethodArguments == null) { if (this.cachedMethodArguments == null) {
return null; return null;

View File

@ -31,6 +31,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.PropertyValues; import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
/** /**
@ -232,6 +233,7 @@ public class InjectionMetadata {
/** /**
* Either this or {@link #inject} needs to be overridden. * Either this or {@link #inject} needs to be overridden.
*/ */
@Nullable
protected Object getResourceToInject(Object target, String requestingBeanName) { protected Object getResourceToInject(Object target, String requestingBeanName) {
return null; return null;
} }

View File

@ -36,6 +36,7 @@ import org.springframework.core.MethodParameter;
import org.springframework.core.annotation.AnnotatedElementUtils; import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationAttributes; import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.annotation.AnnotationUtils; import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert; import org.springframework.util.Assert;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
@ -341,6 +342,7 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
/** /**
* Determine a suggested value from any of the given candidate annotations. * Determine a suggested value from any of the given candidate annotations.
*/ */
@Nullable
protected Object findValue(Annotation[] annotationsToSearch) { protected Object findValue(Annotation[] annotationsToSearch) {
AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes( AnnotationAttributes attr = AnnotatedElementUtils.getMergedAnnotationAttributes(
AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType); AnnotatedElementUtils.forAnnotations(annotationsToSearch), this.valueAnnotationType);

View File

@ -1,4 +1,7 @@
/** /**
* Support package for annotation-driven bean configuration. * Support package for annotation-driven bean configuration.
*/ */
@NonNullApi
package org.springframework.beans.factory.annotation; package org.springframework.beans.factory.annotation;
import org.springframework.lang.NonNullApi;

View File

@ -33,6 +33,7 @@ import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.FactoryBeanNotInitializedException; import org.springframework.beans.factory.FactoryBeanNotInitializedException;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils; import org.springframework.util.ClassUtils;
import org.springframework.util.ObjectUtils; import org.springframework.util.ObjectUtils;
import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils;
@ -225,6 +226,7 @@ public abstract class AbstractFactoryBean<T>
* or {@code null} to indicate a FactoryBeanNotInitializedException * or {@code null} to indicate a FactoryBeanNotInitializedException
* @see org.springframework.beans.factory.FactoryBeanNotInitializedException * @see org.springframework.beans.factory.FactoryBeanNotInitializedException
*/ */
@Nullable
protected Class<?>[] getEarlySingletonInterfaces() { protected Class<?>[] getEarlySingletonInterfaces() {
Class<?> type = getObjectType(); Class<?> type = getObjectType();
return (type != null && type.isInterface() ? new Class<?>[] {type} : null); return (type != null && type.isInterface() ? new Class<?>[] {type} : null);

View File

@ -23,6 +23,7 @@ import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.NoUniqueBeanDefinitionException; import org.springframework.beans.factory.NoUniqueBeanDefinitionException;
import org.springframework.lang.Nullable;
/** /**
* Extension of the {@link org.springframework.beans.factory.BeanFactory} * Extension of the {@link org.springframework.beans.factory.BeanFactory}
@ -337,6 +338,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* @since 2.5 * @since 2.5
* @see #resolveDependency(DependencyDescriptor, String, Set, TypeConverter) * @see #resolveDependency(DependencyDescriptor, String, Set, TypeConverter)
*/ */
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException; Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName) throws BeansException;
/** /**
@ -353,6 +355,7 @@ public interface AutowireCapableBeanFactory extends BeanFactory {
* @since 2.5 * @since 2.5
* @see DependencyDescriptor * @see DependencyDescriptor
*/ */
@Nullable
Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName, Object resolveDependency(DependencyDescriptor descriptor, String requestingBeanName,
Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException; Set<String> autowiredBeanNames, TypeConverter typeConverter) throws BeansException;

View File

@ -19,6 +19,7 @@ package org.springframework.beans.factory.config;
import org.springframework.beans.BeanMetadataElement; import org.springframework.beans.BeanMetadataElement;
import org.springframework.beans.MutablePropertyValues; import org.springframework.beans.MutablePropertyValues;
import org.springframework.core.AttributeAccessor; import org.springframework.core.AttributeAccessor;
import org.springframework.lang.Nullable;
/** /**
* A BeanDefinition describes a bean instance, which has property values, * A BeanDefinition describes a bean instance, which has property values,
@ -84,11 +85,12 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/** /**
* Set the name of the parent definition of this bean definition, if any. * Set the name of the parent definition of this bean definition, if any.
*/ */
void setParentName(String parentName); void setParentName(@Nullable String parentName);
/** /**
* Return the name of the parent definition of this bean definition, if any. * Return the name of the parent definition of this bean definition, if any.
*/ */
@Nullable
String getParentName(); String getParentName();
/** /**
@ -126,6 +128,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
* Return the name of the current target scope for this bean, * Return the name of the current target scope for this bean,
* or {@code null} if not known yet. * or {@code null} if not known yet.
*/ */
@Nullable
String getScope(); String getScope();
/** /**
@ -188,6 +191,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/** /**
* Return the factory bean name, if any. * Return the factory bean name, if any.
*/ */
@Nullable
String getFactoryBeanName(); String getFactoryBeanName();
/** /**
@ -203,6 +207,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
/** /**
* Return a factory method, if any. * Return a factory method, if any.
*/ */
@Nullable
String getFactoryMethodName(); String getFactoryMethodName();
/** /**
@ -260,6 +265,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
* Return a description of the resource that this bean definition * Return a description of the resource that this bean definition
* came from (for the purpose of showing context in case of errors). * came from (for the purpose of showing context in case of errors).
*/ */
@Nullable
String getResourceDescription(); String getResourceDescription();
/** /**
@ -268,6 +274,7 @@ public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
* <p>Note that this method returns the immediate originator. Iterate through the * <p>Note that this method returns the immediate originator. Iterate through the
* originator chain to find the original BeanDefinition as defined by the user. * originator chain to find the original BeanDefinition as defined by the user.
*/ */
@Nullable
BeanDefinition getOriginatingBeanDefinition(); BeanDefinition getOriginatingBeanDefinition();
} }

Some files were not shown because too many files have changed in this diff Show More