Avoid "NullAway.Init" suppression in favor of explicit field handling

Closes gh-36961
This commit is contained in:
Juergen Hoeller
2026-06-23 11:55:58 +02:00
parent 9130ded96f
commit bd405756ab
18 changed files with 140 additions and 131 deletions
@@ -75,11 +75,9 @@ final class InstantiationModelAwarePointcutAdvisorImpl
private @Nullable Advice instantiatedAdvice;
@SuppressWarnings("NullAway.Init")
private Boolean isBeforeAdvice;
private @Nullable Boolean isBeforeAdvice;
@SuppressWarnings("NullAway.Init")
private Boolean isAfterAdvice;
private @Nullable Boolean isAfterAdvice;
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
@@ -198,7 +196,7 @@ final class InstantiationModelAwarePointcutAdvisorImpl
if (this.isBeforeAdvice == null) {
determineAdviceType();
}
return this.isBeforeAdvice;
return (this.isBeforeAdvice == Boolean.TRUE);
}
@Override
@@ -206,7 +204,7 @@ final class InstantiationModelAwarePointcutAdvisorImpl
if (this.isAfterAdvice == null) {
determineAdviceType();
}
return this.isAfterAdvice;
return (this.isAfterAdvice == Boolean.TRUE);
}
/**
@@ -42,8 +42,7 @@ public abstract class AbstractRefreshableTargetSource implements TargetSource, R
/** Logger available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());
@SuppressWarnings("NullAway.Init")
protected Object targetObject;
protected @Nullable Object targetObject;
private long refreshCheckDelay = -1;
@@ -66,11 +65,11 @@ public abstract class AbstractRefreshableTargetSource implements TargetSource, R
@Override
public synchronized Class<?> getTargetClass() {
public synchronized @Nullable Class<?> getTargetClass() {
if (this.targetObject == null) {
refresh();
}
return this.targetObject.getClass();
return (this.targetObject != null ? this.targetObject.getClass() : null);
}
@Override
@@ -100,8 +100,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
private @Nullable PropertyEditorRegistrar defaultEditorRegistrar;
@SuppressWarnings("NullAway.Init")
private Map<Class<?>, PropertyEditor> defaultEditors;
private @Nullable Map<Class<?>, PropertyEditor> defaultEditors;
private @Nullable Map<Class<?>, PropertyEditor> overriddenDefaultEditors;
@@ -201,7 +200,7 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
}
}
if (this.defaultEditors == null) {
createDefaultEditors();
this.defaultEditors = createDefaultEditors();
}
return this.defaultEditors.get(requiredType);
}
@@ -209,75 +208,77 @@ public class PropertyEditorRegistrySupport implements PropertyEditorRegistry {
/**
* Actually register the default editors for this registry instance.
*/
private void createDefaultEditors() {
this.defaultEditors = new HashMap<>(64);
private Map<Class<?>, PropertyEditor> createDefaultEditors() {
Map<Class<?>, PropertyEditor> defaultEditors = new HashMap<>(64);
// Simple editors, without parameterization capabilities.
// The JDK does not contain a default editor for any of these target types.
this.defaultEditors.put(Charset.class, new CharsetEditor());
this.defaultEditors.put(Class.class, new ClassEditor());
this.defaultEditors.put(Class[].class, new ClassArrayEditor());
this.defaultEditors.put(Currency.class, new CurrencyEditor());
this.defaultEditors.put(File.class, new FileEditor());
this.defaultEditors.put(InputStream.class, new InputStreamEditor());
this.defaultEditors.put(InputSource.class, new InputSourceEditor());
this.defaultEditors.put(Locale.class, new LocaleEditor());
this.defaultEditors.put(Path.class, new PathEditor());
this.defaultEditors.put(Pattern.class, new PatternEditor());
this.defaultEditors.put(Properties.class, new PropertiesEditor());
this.defaultEditors.put(Reader.class, new ReaderEditor());
this.defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
this.defaultEditors.put(TimeZone.class, new TimeZoneEditor());
this.defaultEditors.put(URI.class, new URIEditor());
this.defaultEditors.put(URL.class, new URLEditor());
this.defaultEditors.put(UUID.class, new UUIDEditor());
this.defaultEditors.put(ZoneId.class, new ZoneIdEditor());
defaultEditors.put(Charset.class, new CharsetEditor());
defaultEditors.put(Class.class, new ClassEditor());
defaultEditors.put(Class[].class, new ClassArrayEditor());
defaultEditors.put(Currency.class, new CurrencyEditor());
defaultEditors.put(File.class, new FileEditor());
defaultEditors.put(InputStream.class, new InputStreamEditor());
defaultEditors.put(InputSource.class, new InputSourceEditor());
defaultEditors.put(Locale.class, new LocaleEditor());
defaultEditors.put(Path.class, new PathEditor());
defaultEditors.put(Pattern.class, new PatternEditor());
defaultEditors.put(Properties.class, new PropertiesEditor());
defaultEditors.put(Reader.class, new ReaderEditor());
defaultEditors.put(Resource[].class, new ResourceArrayPropertyEditor());
defaultEditors.put(TimeZone.class, new TimeZoneEditor());
defaultEditors.put(URI.class, new URIEditor());
defaultEditors.put(URL.class, new URLEditor());
defaultEditors.put(UUID.class, new UUIDEditor());
defaultEditors.put(ZoneId.class, new ZoneIdEditor());
// Default instances of collection editors.
// Can be overridden by registering custom instances of those as custom editors.
this.defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
this.defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
this.defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
this.defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
this.defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));
defaultEditors.put(Collection.class, new CustomCollectionEditor(Collection.class));
defaultEditors.put(Set.class, new CustomCollectionEditor(Set.class));
defaultEditors.put(SortedSet.class, new CustomCollectionEditor(SortedSet.class));
defaultEditors.put(List.class, new CustomCollectionEditor(List.class));
defaultEditors.put(SortedMap.class, new CustomMapEditor(SortedMap.class));
// Default editors for primitive arrays.
this.defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
this.defaultEditors.put(char[].class, new CharArrayPropertyEditor());
defaultEditors.put(byte[].class, new ByteArrayPropertyEditor());
defaultEditors.put(char[].class, new CharArrayPropertyEditor());
// The JDK does not contain a default editor for char!
this.defaultEditors.put(char.class, new CharacterEditor(false));
this.defaultEditors.put(Character.class, new CharacterEditor(true));
defaultEditors.put(char.class, new CharacterEditor(false));
defaultEditors.put(Character.class, new CharacterEditor(true));
// Spring's CustomBooleanEditor accepts more flag values than the JDK's default editor.
this.defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
this.defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
defaultEditors.put(boolean.class, new CustomBooleanEditor(false));
defaultEditors.put(Boolean.class, new CustomBooleanEditor(true));
// The JDK does not contain default editors for number wrapper types!
// Override JDK primitive number editors with our own CustomNumberEditor.
this.defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
this.defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
this.defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
this.defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
this.defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
this.defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
this.defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
this.defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
this.defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
this.defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
this.defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
this.defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
this.defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
this.defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
defaultEditors.put(byte.class, new CustomNumberEditor(Byte.class, false));
defaultEditors.put(Byte.class, new CustomNumberEditor(Byte.class, true));
defaultEditors.put(short.class, new CustomNumberEditor(Short.class, false));
defaultEditors.put(Short.class, new CustomNumberEditor(Short.class, true));
defaultEditors.put(int.class, new CustomNumberEditor(Integer.class, false));
defaultEditors.put(Integer.class, new CustomNumberEditor(Integer.class, true));
defaultEditors.put(long.class, new CustomNumberEditor(Long.class, false));
defaultEditors.put(Long.class, new CustomNumberEditor(Long.class, true));
defaultEditors.put(float.class, new CustomNumberEditor(Float.class, false));
defaultEditors.put(Float.class, new CustomNumberEditor(Float.class, true));
defaultEditors.put(double.class, new CustomNumberEditor(Double.class, false));
defaultEditors.put(Double.class, new CustomNumberEditor(Double.class, true));
defaultEditors.put(BigDecimal.class, new CustomNumberEditor(BigDecimal.class, true));
defaultEditors.put(BigInteger.class, new CustomNumberEditor(BigInteger.class, true));
// Only register config value editors if explicitly requested.
if (this.configValueEditorsActive) {
StringArrayPropertyEditor sae = new StringArrayPropertyEditor();
this.defaultEditors.put(String[].class, sae);
this.defaultEditors.put(short[].class, sae);
this.defaultEditors.put(int[].class, sae);
this.defaultEditors.put(long[].class, sae);
defaultEditors.put(String[].class, sae);
defaultEditors.put(short[].class, sae);
defaultEditors.put(int[].class, sae);
defaultEditors.put(long[].class, sae);
}
return defaultEditors;
}
/**
@@ -74,8 +74,7 @@ public abstract class AbstractFactoryBean<T>
private boolean initialized = false;
@SuppressWarnings("NullAway.Init")
private T singletonInstance;
private @Nullable T singletonInstance;
private @Nullable T earlySingletonInstance;
@@ -147,7 +146,7 @@ public abstract class AbstractFactoryBean<T>
* @see #getEarlySingletonInterfaces()
*/
@Override
public final T getObject() throws Exception {
public final @Nullable T getObject() throws Exception {
if (isSingleton()) {
return (this.initialized ? this.singletonInstance : getEarlySingletonInstance());
}
@@ -89,15 +89,13 @@ public class PropertyPathFactoryBean implements FactoryBean<Object>, BeanNameAwa
private @Nullable BeanWrapper targetBeanWrapper;
@SuppressWarnings("NullAway.Init")
private String targetBeanName;
private @Nullable String targetBeanName;
private @Nullable String propertyPath;
private @Nullable Class<?> resultType;
@SuppressWarnings("NullAway.Init")
private String beanName;
private @Nullable String beanName;
private @Nullable BeanFactory beanFactory;
@@ -160,25 +158,27 @@ public class PropertyPathFactoryBean implements FactoryBean<Object>, BeanNameAwa
@Override
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
String targetBeanName = this.targetBeanName;
if (this.targetBeanWrapper != null && this.targetBeanName != null) {
if (this.targetBeanWrapper != null && targetBeanName != null) {
throw new IllegalArgumentException("Specify either 'targetObject' or 'targetBeanName', not both");
}
if (this.targetBeanWrapper == null && this.targetBeanName == null) {
if (this.targetBeanWrapper == null && targetBeanName == null) {
if (this.propertyPath != null) {
throw new IllegalArgumentException(
"Specify 'targetObject' or 'targetBeanName' in combination with 'propertyPath'");
}
// No other properties specified: check bean name.
int dotIndex = (this.beanName != null ? this.beanName.indexOf('.') : -1);
if (dotIndex == -1) {
int dotIndex;
if (this.beanName == null || (dotIndex = this.beanName.indexOf('.')) <= 0) {
throw new IllegalArgumentException(
"Neither 'targetObject' nor 'targetBeanName' specified, and PropertyPathFactoryBean " +
"bean name '" + this.beanName + "' does not follow 'beanName.property' syntax");
}
this.targetBeanName = this.beanName.substring(0, dotIndex);
targetBeanName = this.beanName.substring(0, dotIndex);
this.targetBeanName = targetBeanName;
this.propertyPath = this.beanName.substring(dotIndex + 1);
}
@@ -187,9 +187,10 @@ public class PropertyPathFactoryBean implements FactoryBean<Object>, BeanNameAwa
throw new IllegalArgumentException("'propertyPath' is required");
}
if (this.targetBeanWrapper == null && this.beanFactory.isSingleton(this.targetBeanName)) {
if (this.targetBeanWrapper == null && StringUtils.hasLength(targetBeanName) &&
this.beanFactory.isSingleton(targetBeanName)) {
// Eagerly fetch singleton target bean, and determine result type.
Object bean = this.beanFactory.getBean(this.targetBeanName);
Object bean = this.beanFactory.getBean(targetBeanName);
this.targetBeanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(bean);
this.resultType = this.targetBeanWrapper.getPropertyType(this.propertyPath);
}
@@ -41,8 +41,7 @@ import org.springframework.context.annotation.Role;
@Configuration(proxyBeanMethods = false)
public abstract class AbstractJCacheConfiguration extends AbstractCachingConfiguration {
@SuppressWarnings("NullAway.Init")
protected Supplier<@Nullable CacheResolver> exceptionCacheResolver;
protected @Nullable Supplier<@Nullable CacheResolver> exceptionCacheResolver;
@Override
@@ -50,17 +50,13 @@ public abstract class AbstractCachingConfiguration implements ImportAware {
protected @Nullable AnnotationAttributes enableCaching;
@SuppressWarnings("NullAway.Init")
protected Supplier<@Nullable CacheManager> cacheManager;
protected @Nullable Supplier<@Nullable CacheManager> cacheManager;
@SuppressWarnings("NullAway.Init")
protected Supplier<@Nullable CacheResolver> cacheResolver;
protected @Nullable Supplier<@Nullable CacheResolver> cacheResolver;
@SuppressWarnings("NullAway.Init")
protected Supplier<@Nullable KeyGenerator> keyGenerator;
protected @Nullable Supplier<@Nullable KeyGenerator> keyGenerator;
@SuppressWarnings("NullAway.Init")
protected Supplier<@Nullable CacheErrorHandler> errorHandler;
protected @Nullable Supplier<@Nullable CacheErrorHandler> errorHandler;
@Override
@@ -23,6 +23,8 @@ import java.util.Set;
import java.util.function.Function;
import java.util.function.Predicate;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
@@ -124,8 +126,7 @@ public abstract class MergedAnnotationPredicates {
private boolean hasLastValue;
@SuppressWarnings("NullAway.Init")
private Object lastValue;
private @Nullable Object lastValue;
FirstRunOfPredicate(Function<? super MergedAnnotation<A>, ?> valueExtractor) {
Assert.notNull(valueExtractor, "Value extractor must not be null");
@@ -18,6 +18,8 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource;
import org.jspecify.annotations.Nullable;
import org.springframework.util.Assert;
/**
@@ -31,7 +33,7 @@ import org.springframework.util.Assert;
public abstract class AbstractColumnMaxValueIncrementer extends AbstractDataFieldMaxValueIncrementer {
/** The name of the column for this sequence. */
private String columnName;
private @Nullable String columnName;
/** The number of keys buffered in a cache. */
private int cacheSize = 1;
@@ -43,7 +45,6 @@ public abstract class AbstractColumnMaxValueIncrementer extends AbstractDataFiel
* @see #setIncrementerName
* @see #setColumnName
*/
@SuppressWarnings("NullAway.Init")
public AbstractColumnMaxValueIncrementer() {
}
@@ -63,14 +64,14 @@ public abstract class AbstractColumnMaxValueIncrementer extends AbstractDataFiel
/**
* Set the name of the column in the sequence table.
*/
public void setColumnName(String columnName) {
public void setColumnName(@Nullable String columnName) {
this.columnName = columnName;
}
/**
* Return the name of the column in the sequence table.
*/
public String getColumnName() {
public @Nullable String getColumnName() {
return this.columnName;
}
@@ -18,6 +18,8 @@ package org.springframework.jdbc.support.incrementer;
import javax.sql.DataSource;
import org.jspecify.annotations.Nullable;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.dao.DataAccessException;
import org.springframework.util.Assert;
@@ -34,12 +36,10 @@ import org.springframework.util.Assert;
*/
public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldMaxValueIncrementer, InitializingBean {
@SuppressWarnings("NullAway.Init")
private DataSource dataSource;
private @Nullable DataSource dataSource;
/** The name of the sequence/table containing the sequence. */
@SuppressWarnings("NullAway.Init")
private String incrementerName;
private @Nullable String incrementerName;
/** The length to which a string result should be prepended with zeroes. */
protected int paddingLength = 0;
@@ -69,28 +69,40 @@ public abstract class AbstractDataFieldMaxValueIncrementer implements DataFieldM
/**
* Set the data source to retrieve the value from.
*/
public void setDataSource(DataSource dataSource) {
public void setDataSource(@Nullable DataSource dataSource) {
this.dataSource = dataSource;
}
/**
* Return the data source to retrieve the value from.
*/
public DataSource getDataSource() {
public @Nullable DataSource getDataSource() {
return this.dataSource;
}
/**
* Obtain the {@code DataSource} for actual use.
* @return the DataSource (never {@code null})
* @throws IllegalStateException in case of no DataSource set
* @since 7.1
*/
protected DataSource obtainDataSource() {
DataSource dataSource = getDataSource();
Assert.state(dataSource != null, "No DataSource set");
return dataSource;
}
/**
* Set the name of the sequence/table.
*/
public void setIncrementerName(String incrementerName) {
public void setIncrementerName(@Nullable String incrementerName) {
this.incrementerName = incrementerName;
}
/**
* Return the name of the sequence/table.
*/
public String getIncrementerName() {
public @Nullable String getIncrementerName() {
return this.incrementerName;
}
@@ -91,11 +91,12 @@ public abstract class AbstractIdentityColumnMaxValueIncrementer extends Abstract
* are performed on the same connection (otherwise we can't be sure that @@identity
* returns the correct value)
*/
Connection con = DataSourceUtils.getConnection(getDataSource());
DataSource dataSource = obtainDataSource();
Connection con = DataSourceUtils.getConnection(dataSource);
Statement stmt = null;
try {
stmt = con.createStatement();
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
DataSourceUtils.applyTransactionTimeout(stmt, dataSource);
this.valueCache = new long[getCacheSize()];
this.nextValueIndex = 0;
for (int i = 0; i < getCacheSize(); i++) {
@@ -118,7 +119,7 @@ public abstract class AbstractIdentityColumnMaxValueIncrementer extends Abstract
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
DataSourceUtils.releaseConnection(con, dataSource);
}
}
Assert.state(this.valueCache != null, "The cache of values can't be null");
@@ -61,12 +61,13 @@ public abstract class AbstractSequenceMaxValueIncrementer extends AbstractDataFi
*/
@Override
protected long getNextKey() throws DataAccessException {
Connection con = DataSourceUtils.getConnection(getDataSource());
DataSource dataSource = obtainDataSource();
Connection con = DataSourceUtils.getConnection(dataSource);
Statement stmt = null;
ResultSet rs = null;
try {
stmt = con.createStatement();
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
DataSourceUtils.applyTransactionTimeout(stmt, dataSource);
rs = stmt.executeQuery(getSequenceQuery());
if (rs.next()) {
return rs.getLong(1);
@@ -81,7 +82,7 @@ public abstract class AbstractSequenceMaxValueIncrementer extends AbstractDataFi
finally {
JdbcUtils.closeResultSet(rs);
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
DataSourceUtils.releaseConnection(con, dataSource);
}
}
@@ -127,20 +127,21 @@ public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
Connection con = null;
Statement stmt = null;
boolean mustRestoreAutoCommit = false;
DataSource dataSource = obtainDataSource();
try {
if (this.useNewConnection) {
con = getDataSource().getConnection();
con = dataSource.getConnection();
if (con.getAutoCommit()) {
mustRestoreAutoCommit = true;
con.setAutoCommit(false);
}
}
else {
con = DataSourceUtils.getConnection(getDataSource());
con = DataSourceUtils.getConnection(dataSource);
}
stmt = con.createStatement();
if (!this.useNewConnection) {
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
DataSourceUtils.applyTransactionTimeout(stmt, dataSource);
}
// Increment the sequence column...
String columnName = getColumnName();
@@ -185,7 +186,7 @@ public class MySQLMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
JdbcUtils.closeConnection(con);
}
else {
DataSourceUtils.releaseConnection(con, getDataSource());
DataSourceUtils.releaseConnection(con, dataSource);
}
}
}
@@ -59,11 +59,12 @@ public class SqliteMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
@Override
protected synchronized long getNextKey() {
Connection con = DataSourceUtils.getConnection(getDataSource());
DataSource dataSource = obtainDataSource();
Connection con = DataSourceUtils.getConnection(dataSource);
Statement stmt = null;
try {
stmt = con.createStatement();
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
DataSourceUtils.applyTransactionTimeout(stmt, dataSource);
stmt.executeUpdate("insert into " + getIncrementerName() + " values(null)");
ResultSet rs = stmt.executeQuery("select max(rowid) from " + getIncrementerName());
if (!rs.next()) {
@@ -78,7 +79,7 @@ public class SqliteMaxValueIncrementer extends AbstractColumnMaxValueIncrementer
}
finally {
JdbcUtils.closeStatement(stmt);
DataSourceUtils.releaseConnection(con, getDataSource());
DataSourceUtils.releaseConnection(con, dataSource);
}
}
@@ -44,8 +44,7 @@ import org.springframework.web.multipart.MultipartHttpServletRequest;
public abstract class AbstractMultipartHttpServletRequest extends HttpServletRequestWrapper
implements MultipartHttpServletRequest {
@SuppressWarnings("NullAway.Init")
private MultiValueMap<String, MultipartFile> multipartFiles;
private @Nullable MultiValueMap<String, MultipartFile> multipartFiles;
/**
@@ -140,7 +139,7 @@ public abstract class AbstractMultipartHttpServletRequest extends HttpServletReq
if (this.multipartFiles == null) {
initializeMultipart();
}
return this.multipartFiles;
return (this.multipartFiles != null ? this.multipartFiles : new LinkedMultiValueMap<>(Collections.emptyMap()));
}
/**
@@ -45,11 +45,9 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
private static final String CONTENT_TYPE = "Content-Type";
@SuppressWarnings("NullAway.Init")
private Map<String, String[]> multipartParameters;
private @Nullable Map<String, String[]> multipartParameters;
@SuppressWarnings("NullAway.Init")
private Map<String, String> multipartParameterContentTypes;
private @Nullable Map<String, String> multipartParameterContentTypes;
/**
@@ -170,7 +168,7 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
if (this.multipartParameters == null) {
initializeMultipart();
}
return this.multipartParameters;
return (this.multipartParameters != null ? this.multipartParameters : Collections.emptyMap());
}
/**
@@ -190,7 +188,8 @@ public class DefaultMultipartHttpServletRequest extends AbstractMultipartHttpSer
if (this.multipartParameterContentTypes == null) {
initializeMultipart();
}
return this.multipartParameterContentTypes;
return (this.multipartParameterContentTypes != null ? this.multipartParameterContentTypes :
Collections.emptyMap());
}
}
@@ -58,8 +58,7 @@ import org.springframework.web.multipart.MultipartFile;
*/
public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpServletRequest {
@SuppressWarnings("NullAway.Init")
private Set<String> multipartParameterNames;
private @Nullable Set<String> multipartParameterNames;
/**
@@ -144,7 +143,7 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
if (this.multipartParameterNames == null) {
initializeMultipart();
}
if (this.multipartParameterNames.isEmpty()) {
if (CollectionUtils.isEmpty(this.multipartParameterNames)) {
return super.getParameterNames();
}
@@ -164,7 +163,7 @@ public class StandardMultipartHttpServletRequest extends AbstractMultipartHttpSe
if (this.multipartParameterNames == null) {
initializeMultipart();
}
if (this.multipartParameterNames.isEmpty()) {
if (CollectionUtils.isEmpty(this.multipartParameterNames)) {
return super.getParameterMap();
}
@@ -86,8 +86,7 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
private WebSessionManager sessionManager = new DefaultWebSessionManager();
@SuppressWarnings("NullAway.Init")
private ServerCodecConfigurer codecConfigurer;
private @Nullable ServerCodecConfigurer codecConfigurer;
private LocaleContextResolver localeContextResolver = new AcceptHeaderLocaleContextResolver();
@@ -153,10 +152,12 @@ public class HttpWebHandlerAdapter extends WebHandlerDecorator implements HttpHa
* Return the configured {@link ServerCodecConfigurer}.
*/
public ServerCodecConfigurer getCodecConfigurer() {
if (this.codecConfigurer == null) {
setCodecConfigurer(ServerCodecConfigurer.create());
ServerCodecConfigurer codecConfigurer = this.codecConfigurer;
if (codecConfigurer == null) {
codecConfigurer = ServerCodecConfigurer.create();
setCodecConfigurer(codecConfigurer);
}
return this.codecConfigurer;
return codecConfigurer;
}
/**