Update code regarding null-safety semantics

See gh-30083
This commit is contained in:
Sam Brannen
2023-03-13 21:19:46 +01:00
parent b617e16d8d
commit a6dab10309
33 changed files with 120 additions and 46 deletions

View File

@@ -58,6 +58,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
protected final Log logger = LogFactory.getLog(getClass());
@Nullable
private ConfigurableBeanFactory beanFactory;
/** Internally used DefaultListableBeanFactory instances, keyed by bean name. */
@@ -76,6 +77,7 @@ public abstract class AbstractBeanFactoryBasedTargetSourceCreator
/**
* Return the BeanFactory that this TargetSourceCreators runs in.
*/
@Nullable
protected final BeanFactory getBeanFactory() {
return this.beanFactory;
}

View File

@@ -24,6 +24,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.TargetSource;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
/**
@@ -169,7 +170,7 @@ public abstract class AbstractBeanFactoryBasedTargetSource implements TargetSour
@Override
public boolean equals(Object other) {
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}

View File

@@ -131,7 +131,7 @@ public final class EmptyTargetSource implements TargetSource, Serializable {
}
@Override
public boolean equals(Object other) {
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}

View File

@@ -19,6 +19,7 @@ package org.springframework.aop.target;
import java.io.Serializable;
import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
/**
@@ -100,7 +101,7 @@ public class HotSwappableTargetSource implements TargetSource, Serializable {
* objects are equal.
*/
@Override
public boolean equals(Object obj) {
public boolean equals(@Nullable Object obj) {
return (this == obj || (obj instanceof HotSwappableTargetSource that &&
this.target.equals(that.target)));
}

View File

@@ -65,7 +65,6 @@ public class LazyInitTargetSource extends AbstractBeanFactoryBasedTargetSource {
@Override
@Nullable
public synchronized Object getTarget() throws BeansException {
if (this.target == null) {
this.target = getBeanFactory().getBean(getTargetBeanName());

View File

@@ -19,6 +19,7 @@ package org.springframework.aop.target;
import java.io.Serializable;
import org.springframework.aop.TargetSource;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -82,7 +83,7 @@ public class SingletonTargetSource implements TargetSource, Serializable {
* targets or the targets are equal.
*/
@Override
public boolean equals(Object other) {
public boolean equals(@Nullable Object other) {
if (this == other) {
return true;
}

View File

@@ -88,8 +88,9 @@ abstract class PropertyDescriptorUtils {
BasicPropertyDescriptor pd = pdMap.get(propertyName);
if (pd != null) {
if (setter) {
if (pd.getWriteMethod() == null ||
pd.getWriteMethod().getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
Method writedMethod = pd.getWriteMethod();
if (writedMethod == null ||
writedMethod.getParameterTypes()[0].isAssignableFrom(method.getParameterTypes()[0])) {
pd.setWriteMethod(method);
}
else {
@@ -97,8 +98,9 @@ abstract class PropertyDescriptorUtils {
}
}
else {
if (pd.getReadMethod() == null ||
(pd.getReadMethod().getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
Method readMethod = pd.getReadMethod();
if (readMethod == null ||
(readMethod.getReturnType() == method.getReturnType() && method.getName().startsWith("is"))) {
pd.setReadMethod(method);
}
}

View File

@@ -280,6 +280,7 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
}
@Override
@Nullable
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
Class<?> beanClass = registeredBean.getBeanClass();
String beanName = registeredBean.getBeanName();
@@ -323,10 +324,10 @@ public class AutowiredAnnotationBeanPostProcessor implements SmartInstantiationA
checkLookupMethods(beanClass, beanName);
// Pick up subclass with fresh lookup method override from above
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacbf) {
if (this.beanFactory instanceof AbstractAutowireCapableBeanFactory aacBeanFactory) {
RootBeanDefinition mbd = (RootBeanDefinition) this.beanFactory.getMergedBeanDefinition(beanName);
if (mbd.getFactoryMethodName() == null && mbd.hasBeanClass()) {
return aacbf.getInstantiationStrategy().getActualBeanClass(mbd, beanName, this.beanFactory);
return aacBeanFactory.getInstantiationStrategy().getActualBeanClass(mbd, beanName, aacBeanFactory);
}
}
return beanClass;

View File

@@ -157,6 +157,7 @@ public class InitDestroyAnnotationBeanPostProcessor implements DestructionAwareB
}
@Override
@Nullable
public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
RootBeanDefinition beanDefinition = registeredBean.getMergedBeanDefinition();
beanDefinition.resolveDestroyMethodIfNecessary();

View File

@@ -20,6 +20,7 @@ import java.util.stream.Stream;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.lang.Nullable;
import org.springframework.util.ClassUtils;
/**
@@ -31,7 +32,7 @@ import org.springframework.util.ClassUtils;
class JakartaAnnotationsRuntimeHints implements RuntimeHintsRegistrar {
@Override
public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
public void registerHints(RuntimeHints hints, @Nullable ClassLoader classLoader) {
if (ClassUtils.isPresent("jakarta.inject.Inject", classLoader)) {
Stream.of("jakarta.inject.Inject", "jakarta.inject.Qualifier").forEach(annotationType ->
hints.reflection().registerType(ClassUtils.resolveClassName(annotationType, classLoader)));

View File

@@ -25,6 +25,7 @@ import java.util.Set;
import org.springframework.beans.SimpleTypeConverter;
import org.springframework.beans.TypeConverter;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.DependencyDescriptor;
@@ -240,10 +241,11 @@ public class QualifierAnnotationAutowireCandidateResolver extends GenericTypeAwa
}
}
if (targetAnnotation == null) {
BeanFactory beanFactory = getBeanFactory();
// Look for matching annotation on the target class
if (getBeanFactory() != null) {
if (beanFactory != null) {
try {
Class<?> beanType = getBeanFactory().getType(bdHolder.getBeanName());
Class<?> beanType = beanFactory.getType(bdHolder.getBeanName());
if (beanType != null) {
targetAnnotation = AnnotationUtils.getAnnotation(ClassUtils.getUserClass(beanType), type);
}

View File

@@ -188,7 +188,7 @@ public class ConstructorArgumentValues {
* rather than matched multiple times.
* @param value the argument value
*/
public void addGenericArgumentValue(Object value) {
public void addGenericArgumentValue(@Nullable Object value) {
this.genericArgumentValues.add(new ValueHolder(value));
}

View File

@@ -53,6 +53,7 @@ import org.springframework.beans.factory.xml.XmlReaderContext;
import org.springframework.core.io.DescriptiveResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
@@ -149,8 +150,10 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
private MetaClass metaClass = GroovySystem.getMetaClassRegistry().getMetaClass(getClass());
@Nullable
private Binding binding;
@Nullable
private GroovyBeanDefinitionWrapper currentBeanDefinition;
@@ -203,6 +206,7 @@ public class GroovyBeanDefinitionReader extends AbstractBeanDefinitionReader imp
/**
* Return a specified binding for Groovy variables, if any.
*/
@Nullable
public Binding getBinding() {
return this.binding;
}

View File

@@ -30,6 +30,8 @@ import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
/**
@@ -55,35 +57,41 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
FACTORY_BEAN, FACTORY_METHOD, INIT_METHOD, DESTROY_METHOD, SINGLETON);
@Nullable
private String beanName;
private Class<?> clazz;
@Nullable
private final Class<?> clazz;
private Collection<?> constructorArgs;
@Nullable
private final Collection<?> constructorArgs;
@Nullable
private AbstractBeanDefinition definition;
@Nullable
private BeanWrapper definitionWrapper;
@Nullable
private String parentName;
public GroovyBeanDefinitionWrapper(String beanName) {
this.beanName = beanName;
GroovyBeanDefinitionWrapper(String beanName) {
this(beanName, null);
}
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz) {
this.beanName = beanName;
this.clazz = clazz;
GroovyBeanDefinitionWrapper(@Nullable String beanName, @Nullable Class<?> clazz) {
this(beanName, clazz, null);
}
public GroovyBeanDefinitionWrapper(String beanName, Class<?> clazz, Collection<?> constructorArgs) {
GroovyBeanDefinitionWrapper(@Nullable String beanName, Class<?> clazz, @Nullable Collection<?> constructorArgs) {
this.beanName = beanName;
this.clazz = clazz;
this.constructorArgs = constructorArgs;
}
@Nullable
public String getBeanName() {
return this.beanName;
}
@@ -151,6 +159,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
@Override
public Object getProperty(String property) {
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
if (this.definitionWrapper.isReadableProperty(property)) {
return this.definitionWrapper.getPropertyValue(property);
}
@@ -167,6 +176,7 @@ class GroovyBeanDefinitionWrapper extends GroovyObjectSupport {
}
else {
AbstractBeanDefinition bd = getBeanDefinition();
Assert.state(this.definitionWrapper != null, "BeanDefinition wrapper not initialized");
if (AUTOWIRE.equals(property)) {
if ("byName".equals(newValue)) {
bd.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_NAME);

View File

@@ -31,6 +31,7 @@ import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParserDelegate;
import org.springframework.lang.Nullable;
/**
* Used by GroovyBeanDefinitionReader to read a Spring XML namespace expression
@@ -68,6 +69,7 @@ class GroovyDynamicElementReader extends GroovyObjectSupport {
@Override
@Nullable
public Object invokeMethod(String name, Object obj) {
Object[] args = (Object[]) obj;
if (name.equals("doCall")) {

View File

@@ -1958,6 +1958,7 @@ public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFac
}
@Override
@Nullable
public String getDependencyName() {
return null;
}

View File

@@ -879,10 +879,12 @@ public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccess
*/
@Override
public MutablePropertyValues getPropertyValues() {
if (this.propertyValues == null) {
this.propertyValues = new MutablePropertyValues();
MutablePropertyValues pvs = this.propertyValues;
if (pvs == null) {
pvs = new MutablePropertyValues();
this.propertyValues = pvs;
}
return this.propertyValues;
return pvs;
}
/**

View File

@@ -340,7 +340,7 @@ public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements
* (within the entire factory).
* @param beanName the name of the bean
*/
public boolean isSingletonCurrentlyInCreation(String beanName) {
public boolean isSingletonCurrentlyInCreation(@Nullable String beanName) {
return this.singletonsCurrentlyInCreation.contains(beanName);
}

View File

@@ -547,7 +547,8 @@ public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
* @see DefaultNamespaceHandlerResolver#DefaultNamespaceHandlerResolver(ClassLoader)
*/
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
ResourceLoader resourceLoader = getResourceLoader();
ClassLoader cl = (resourceLoader != null ? resourceLoader.getClassLoader() : getBeanClassLoader());
return new DefaultNamespaceHandlerResolver(cl);
}

View File

@@ -111,6 +111,7 @@ public class ArgumentConvertingMethodInvoker extends MethodInvoker {
* @see #doFindMatchingMethod
*/
@Override
@Nullable
protected Method findMatchingMethod() {
Method matchingMethod = super.findMatchingMethod();
// Second pass: look for method where arguments can be converted to parameter types.

View File

@@ -23,6 +23,7 @@ import org.springframework.beans.factory.parsing.BeanComponentDefinition;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.lang.Nullable;
/**
* {@link BeanDefinitionParser} responsible for parsing the
@@ -44,6 +45,7 @@ class SpringConfiguredBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
if (!parserContext.getRegistry().containsBeanDefinition(BEAN_CONFIGURER_ASPECT_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();

View File

@@ -23,6 +23,7 @@ import java.util.concurrent.Future;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;
/**
@@ -40,6 +41,7 @@ class CallableInterceptorChain {
private int preProcessIndex = -1;
@Nullable
private volatile Future<?> taskFuture;
@@ -66,7 +68,7 @@ class CallableInterceptorChain {
}
}
public Object applyPostProcess(NativeWebRequest request, Callable<?> task, Object concurrentResult) {
public Object applyPostProcess(NativeWebRequest request, Callable<?> task, @Nullable Object concurrentResult) {
Throwable exceptionResult = null;
for (int i = this.preProcessIndex; i >= 0; i--) {
try {

View File

@@ -19,6 +19,7 @@ package org.springframework.web.context.request.async;
import java.util.concurrent.Callable;
import org.springframework.core.task.AsyncTaskExecutor;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;
/**
@@ -104,7 +105,7 @@ public interface CallableProcessingInterceptor {
* @throws Exception in case of errors
*/
default <T> void postProcess(NativeWebRequest request, Callable<T> task,
Object concurrentResult) throws Exception {
@Nullable Object concurrentResult) throws Exception {
}
/**

View File

@@ -48,6 +48,7 @@ import org.springframework.web.context.request.NativeWebRequest;
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Rob Winch
* @author Sam Brannen
* @since 3.2
* @param <T> the result type
*/
@@ -63,14 +64,19 @@ public class DeferredResult<T> {
private final Supplier<?> timeoutResult;
@Nullable
private Runnable timeoutCallback;
@Nullable
private Consumer<Throwable> errorCallback;
@Nullable
private Runnable completionCallback;
@Nullable
private DeferredResultHandler resultHandler;
@Nullable
private volatile Object result = RESULT_NONE;
private volatile boolean expired;
@@ -340,7 +346,7 @@ public class DeferredResult<T> {
@FunctionalInterface
public interface DeferredResultHandler {
void handleResult(Object result);
void handleResult(@Nullable Object result);
}
}

View File

@@ -21,6 +21,7 @@ import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;
/**
@@ -57,8 +58,9 @@ class DeferredResultInterceptorChain {
}
}
@Nullable
public Object applyPostProcess(NativeWebRequest request, DeferredResult<?> deferredResult,
Object concurrentResult) {
@Nullable Object concurrentResult) {
try {
for (int i = this.preProcessingIndex; i >= 0; i--) {

View File

@@ -16,6 +16,7 @@
package org.springframework.web.context.request.async;
import org.springframework.lang.Nullable;
import org.springframework.web.context.request.NativeWebRequest;
/**
@@ -82,7 +83,7 @@ public interface DeferredResultProcessingInterceptor {
* @throws Exception in case of errors
*/
default <T> void postProcess(NativeWebRequest request, DeferredResult<T> deferredResult,
Object concurrentResult) throws Exception {
@Nullable Object concurrentResult) throws Exception {
}
/**

View File

@@ -28,6 +28,7 @@ import jakarta.servlet.AsyncListener;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.web.context.request.ServletWebRequest;
@@ -44,10 +45,6 @@ import org.springframework.web.context.request.ServletWebRequest;
*/
public class StandardServletAsyncWebRequest extends ServletWebRequest implements AsyncWebRequest, AsyncListener {
private Long timeout;
private AsyncContext asyncContext;
private final AtomicBoolean asyncCompleted = new AtomicBoolean();
private final List<Runnable> timeoutHandlers = new ArrayList<>();
@@ -56,6 +53,12 @@ public class StandardServletAsyncWebRequest extends ServletWebRequest implements
private final List<Runnable> completionHandlers = new ArrayList<>();
@Nullable
private Long timeout;
@Nullable
private AsyncContext asyncContext;
/**
* Create a new instance for the given request/response pair.

View File

@@ -52,6 +52,7 @@ import org.springframework.web.context.request.async.DeferredResult.DeferredResu
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.2
* @see org.springframework.web.context.request.AsyncWebRequestInterceptor
* @see org.springframework.web.servlet.AsyncHandlerInterceptor
@@ -76,12 +77,15 @@ public final class WebAsyncManager {
private static Boolean taskExecutorWarning = true;
@Nullable
private AsyncWebRequest asyncWebRequest;
private AsyncTaskExecutor taskExecutor = DEFAULT_TASK_EXECUTOR;
@Nullable
private volatile Object concurrentResult = RESULT_NONE;
@Nullable
private volatile Object[] concurrentResultContext;
/*
@@ -164,6 +168,7 @@ public final class WebAsyncManager {
* concurrent handling.
* @see #clearConcurrentResult()
*/
@Nullable
public Object[] getConcurrentResultContext() {
return this.concurrentResultContext;
}
@@ -377,7 +382,7 @@ public final class WebAsyncManager {
return request != null ? request.getRequestURI() : "servlet container";
}
private void setConcurrentResultAndDispatch(Object result) {
private void setConcurrentResultAndDispatch(@Nullable Object result) {
synchronized (WebAsyncManager.this) {
if (this.concurrentResult != RESULT_NONE) {
return;

View File

@@ -30,6 +30,7 @@ import org.springframework.web.context.request.NativeWebRequest;
*
* @author Rossen Stoyanchev
* @author Juergen Hoeller
* @author Sam Brannen
* @since 3.2
* @param <V> the value type
*/
@@ -37,11 +38,14 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
private final Callable<V> callable;
private Long timeout;
@Nullable
private final Long timeout;
private AsyncTaskExecutor executor;
@Nullable
private final AsyncTaskExecutor executor;
private String executorName;
@Nullable
private final String executorName;
private BeanFactory beanFactory;
@@ -59,6 +63,9 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
public WebAsyncTask(Callable<V> callable) {
Assert.notNull(callable, "Callable must not be null");
this.callable = callable;
this.timeout = null;
this.executor = null;
this.executorName = null;
}
/**
@@ -67,8 +74,11 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(long timeout, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
this.callable = callable;
this.timeout = timeout;
this.executor = null;
this.executorName = null;
}
/**
@@ -78,10 +88,12 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(@Nullable Long timeout, String executorName, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
Assert.notNull(executorName, "Executor name must not be null");
this.executorName = executorName;
this.callable = callable;
this.timeout = timeout;
this.executor = null;
this.executorName = executorName;
}
/**
@@ -91,10 +103,12 @@ public class WebAsyncTask<V> implements BeanFactoryAware {
* @param callable the callable for concurrent handling
*/
public WebAsyncTask(@Nullable Long timeout, AsyncTaskExecutor executor, Callable<V> callable) {
this(callable);
Assert.notNull(callable, "Callable must not be null");
Assert.notNull(executor, "Executor must not be null");
this.executor = executor;
this.callable = callable;
this.timeout = timeout;
this.executor = executor;
this.executorName = null;
}

View File

@@ -21,6 +21,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.springframework.lang.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.web.server.ServerWebExchange;
@@ -142,6 +143,7 @@ public class CompositeRequestCondition extends AbstractRequestCondition<Composit
* <p>An empty {@code CompositeRequestCondition} matches to all requests.
*/
@Override
@Nullable
public CompositeRequestCondition getMatchingCondition(ServerWebExchange exchange) {
if (isEmpty()) {
return this;

View File

@@ -194,6 +194,7 @@ public final class ConsumesRequestCondition extends AbstractRequestCondition<Con
* or {@code null} if no expressions match.
*/
@Override
@Nullable
public ConsumesRequestCondition getMatchingCondition(ServerWebExchange exchange) {
ServerHttpRequest request = exchange.getRequest();
if (CorsUtils.isPreFlightRequest(request)) {

View File

@@ -21,6 +21,7 @@ import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.Set;
import org.springframework.lang.Nullable;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.server.ServerWebExchange;
@@ -104,6 +105,7 @@ public final class ParamsRequestCondition extends AbstractRequestCondition<Param
* or {@code null} otherwise.
*/
@Override
@Nullable
public ParamsRequestCondition getMatchingCondition(ServerWebExchange exchange) {
for (ParamExpression expression : this.expressions) {
if (!expression.match(exchange)) {

View File

@@ -99,6 +99,7 @@ public final class RequestConditionHolder extends AbstractRequestCondition<Reque
* holder, return the same holder instance.
*/
@Override
@Nullable
public RequestConditionHolder getMatchingCondition(ServerWebExchange exchange) {
if (this.condition == null) {
return this;