Skip to content

Commit 9fc4fb1

Browse files
committed
Nullability fine-tuning around bean properties
Issue: SPR-15720 Issue: SPR-15792
1 parent 06fc092 commit 9fc4fb1

File tree

31 files changed

+243
-206
lines changed

31 files changed

+243
-206
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/config/FieldRetrievingFactoryBean.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ public Object getTargetObject() {
126126
* @see #setTargetObject
127127
*/
128128
public void setTargetField(@Nullable String targetField) {
129-
this.targetField = StringUtils.trimAllWhitespace(targetField);
129+
this.targetField = (targetField != null ? StringUtils.trimAllWhitespace(targetField) : null);
130130
}
131131

132132
/**

spring-context/src/main/java/org/springframework/cache/interceptor/CacheAspectSupport.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,7 @@ public abstract class CacheAspectSupport extends AbstractCacheInvoker
8181

8282
protected final Log logger = LogFactory.getLog(getClass());
8383

84-
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache =
85-
new ConcurrentHashMap<>(1024);
84+
private final Map<CacheOperationCacheKey, CacheOperationMetadata> metadataCache = new ConcurrentHashMap<>(1024);
8685

8786
private final CacheOperationExpressionEvaluator evaluator = new CacheOperationExpressionEvaluator();
8887

@@ -186,6 +185,7 @@ public void afterPropertiesSet() {
186185
public void afterSingletonsInstantiated() {
187186
if (getCacheResolver() == null) {
188187
// Lazily initialize cache resolver via default cache manager...
188+
Assert.state(this.beanFactory != null, "CacheResolver or BeanFactory must be set on cache aspect");
189189
try {
190190
setCacheManager(this.beanFactory.getBean(CacheManager.class));
191191
}
@@ -289,6 +289,10 @@ else if (StringUtils.hasText(operation.getCacheManager())) {
289289
* @see CacheOperation#cacheResolver
290290
*/
291291
protected <T> T getBean(String beanName, Class<T> expectedType) {
292+
if (this.beanFactory == null) {
293+
throw new IllegalStateException(
294+
"BeanFactory must be set on cache aspect for " + expectedType.getSimpleName() + " retrieval");
295+
}
292296
return BeanFactoryAnnotationUtils.qualifiedBeanOfType(this.beanFactory, expectedType, beanName);
293297
}
294298

spring-context/src/main/java/org/springframework/context/support/AbstractResourceBasedMessageSource.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2016 the original author or authors.
2+
* Copyright 2002-2017 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -38,6 +38,7 @@ public abstract class AbstractResourceBasedMessageSource extends AbstractMessage
3838

3939
private final Set<String> basenameSet = new LinkedHashSet<>(4);
4040

41+
@Nullable
4142
private String defaultEncoding;
4243

4344
private boolean fallbackToSystemLocale = true;

spring-context/src/main/java/org/springframework/validation/DataBinder.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -535,9 +535,6 @@ public void setValidator(@Nullable Validator validator) {
535535
}
536536

537537
private void assertValidators(Validator... validators) {
538-
if (validators == null) {
539-
return;
540-
}
541538
for (Validator validator : validators) {
542539
if (validator != null && (getTarget() != null && !validator.supports(getTarget().getClass()))) {
543540
throw new IllegalStateException("Invalid target for Validator [" + validator + "]: " + getTarget());

spring-core/src/main/java/org/springframework/util/CustomizableThreadCreator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public class CustomizableThreadCreator implements Serializable {
4141

4242
private boolean daemon = false;
4343

44+
@Nullable
4445
private ThreadGroup threadGroup;
4546

4647
private final AtomicInteger threadCount = new AtomicInteger(0);

spring-core/src/main/java/org/springframework/util/concurrent/ListenableFutureCallbackRegistry.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ public void addFailureCallback(FailureCallback callback) {
132132
* added callbacks with the given result.
133133
* @param result the result to trigger the callbacks with
134134
*/
135-
public void success(T result) {
135+
public void success(@Nullable T result) {
136136
synchronized (this.mutex) {
137137
this.state = State.SUCCESS;
138138
this.result = result;

spring-core/src/main/java/org/springframework/util/xml/AbstractXMLReader.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ public void setFeature(String name, boolean value) throws SAXNotRecognizedExcept
144144
* handler. The property name for a lexical handler is {@code http://xml.org/sax/properties/lexical-handler}.
145145
*/
146146
@Override
147+
@Nullable
147148
public Object getProperty(String name) throws SAXNotRecognizedException, SAXNotSupportedException {
148149
if ("http://xml.org/sax/properties/lexical-handler".equals(name)) {
149150
return this.lexicalHandler;

spring-jdbc/src/main/java/org/springframework/jdbc/core/metadata/CallMetaDataContext.java

Lines changed: 36 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,19 @@ public boolean isNamedBinding() {
244244
}
245245

246246

247+
/**
248+
* Initialize this class with metadata from the database.
249+
* @param dataSource the DataSource used to retrieve metadata
250+
*/
251+
public void initializeMetaData(DataSource dataSource) {
252+
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
253+
}
254+
255+
private CallMetaDataProvider obtainMetaDataProvider() {
256+
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider - call initializeMetaData first");
257+
return this.metaDataProvider;
258+
}
259+
247260
/**
248261
* Create a ReturnResultSetParameter/SqlOutParameter depending on the support provided
249262
* by the JDBC driver used for the database in use.
@@ -252,13 +265,13 @@ public boolean isNamedBinding() {
252265
* @return the appropriate SqlParameter
253266
*/
254267
public SqlParameter createReturnResultSetParameter(String parameterName, RowMapper<?> rowMapper) {
255-
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
256-
if (this.metaDataProvider.isReturnResultSetSupported()) {
268+
CallMetaDataProvider provider = obtainMetaDataProvider();
269+
if (provider.isReturnResultSetSupported()) {
257270
return new SqlReturnResultSet(parameterName, rowMapper);
258271
}
259272
else {
260-
if (this.metaDataProvider.isRefCursorSupported()) {
261-
return new SqlOutParameter(parameterName, this.metaDataProvider.getRefCursorSqlType(), rowMapper);
273+
if (provider.isRefCursorSupported()) {
274+
return new SqlOutParameter(parameterName, provider.getRefCursorSqlType(), rowMapper);
262275
}
263276
else {
264277
throw new InvalidDataAccessApiUsageException("Return of a ResultSet from a stored procedure is not supported.");
@@ -290,14 +303,6 @@ public List<SqlParameter> getCallParameters() {
290303
return this.callParameters;
291304
}
292305

293-
/**
294-
* Initialize this class with metadata from the database.
295-
* @param dataSource the DataSource used to retrieve metadata
296-
*/
297-
public void initializeMetaData(DataSource dataSource) {
298-
this.metaDataProvider = CallMetaDataProviderFactory.createMetaDataProvider(dataSource, this);
299-
}
300-
301306
/**
302307
* Process the list of parameters provided, and if procedure column metadata is used,
303308
* the parameters will be matched against the metadata information and any missing
@@ -312,7 +317,7 @@ public void processParameters(List<SqlParameter> parameters) {
312317
* Reconcile the provided parameters with available metadata and add new ones where appropriate.
313318
*/
314319
protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters) {
315-
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
320+
CallMetaDataProvider provider = obtainMetaDataProvider();
316321

317322
final List<SqlParameter> declaredReturnParams = new ArrayList<>();
318323
final Map<String, SqlParameter> declaredParams = new LinkedHashMap<>();
@@ -321,7 +326,7 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
321326
List<String> metaDataParamNames = new ArrayList<>();
322327

323328
// Get the names of the meta data parameters
324-
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
329+
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
325330
if (meta.getParameterType() != DatabaseMetaData.procedureColumnReturn) {
326331
metaDataParamNames.add(lowerCase(meta.getParameterName()));
327332
}
@@ -338,7 +343,7 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
338343
throw new IllegalArgumentException("Anonymous parameters not supported for calls - " +
339344
"please specify a name for the parameter of SQL type " + param.getSqlType());
340345
}
341-
String paramNameToMatch = lowerCase(this.metaDataProvider.parameterNameToUse(paramName));
346+
String paramNameToMatch = lowerCase(provider.parameterNameToUse(paramName));
342347
declaredParams.put(paramNameToMatch, param);
343348
if (param instanceof SqlOutParameter) {
344349
outParamNames.add(paramName);
@@ -360,24 +365,23 @@ protected List<SqlParameter> reconcileParameters(List<SqlParameter> parameters)
360365
List<SqlParameter> workParams = new ArrayList<>();
361366
workParams.addAll(declaredReturnParams);
362367

363-
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
368+
if (!provider.isProcedureColumnMetaDataUsed()) {
364369
workParams.addAll(declaredParams.values());
365370
return workParams;
366371
}
367372

368373
Map<String, String> limitedInParamNamesMap = new HashMap<>(this.limitedInParameterNames.size());
369374
for (String limitedParamName : this.limitedInParameterNames) {
370-
limitedInParamNamesMap.put(
371-
lowerCase(this.metaDataProvider.parameterNameToUse(limitedParamName)), limitedParamName);
375+
limitedInParamNamesMap.put(lowerCase(provider.parameterNameToUse(limitedParamName)), limitedParamName);
372376
}
373377

374-
for (CallParameterMetaData meta : this.metaDataProvider.getCallParameterMetaData()) {
378+
for (CallParameterMetaData meta : provider.getCallParameterMetaData()) {
375379
String paramName = meta.getParameterName();
376380
String paramNameToCheck = null;
377381
if (paramName != null) {
378-
paramNameToCheck = lowerCase(this.metaDataProvider.parameterNameToUse(paramName));
382+
paramNameToCheck = lowerCase(provider.parameterNameToUse(paramName));
379383
}
380-
String paramNameToUse = this.metaDataProvider.parameterNameToUse(paramName);
384+
String paramNameToUse = provider.parameterNameToUse(paramName);
381385
if (declaredParams.containsKey(paramNameToCheck) ||
382386
(meta.getParameterType() == DatabaseMetaData.procedureColumnReturn && returnDeclared)) {
383387
SqlParameter param;
@@ -409,15 +413,15 @@ else if (paramName != null) {
409413
else {
410414
if (meta.getParameterType() == DatabaseMetaData.procedureColumnReturn) {
411415
if (!isFunction() && !isReturnValueRequired() && paramName != null &&
412-
this.metaDataProvider.byPassReturnParameter(paramName)) {
416+
provider.byPassReturnParameter(paramName)) {
413417
if (logger.isDebugEnabled()) {
414418
logger.debug("Bypassing metadata return parameter for '" + paramName + "'");
415419
}
416420
}
417421
else {
418422
String returnNameToUse =
419423
(StringUtils.hasLength(paramNameToUse) ? paramNameToUse : getFunctionReturnName());
420-
workParams.add(this.metaDataProvider.createDefaultOutParameter(returnNameToUse, meta));
424+
workParams.add(provider.createDefaultOutParameter(returnNameToUse, meta));
421425
if (isFunction()) {
422426
setFunctionReturnName(returnNameToUse);
423427
outParamNames.add(returnNameToUse);
@@ -432,14 +436,14 @@ else if (paramName != null) {
432436
paramNameToUse = "";
433437
}
434438
if (meta.getParameterType() == DatabaseMetaData.procedureColumnOut) {
435-
workParams.add(this.metaDataProvider.createDefaultOutParameter(paramNameToUse, meta));
439+
workParams.add(provider.createDefaultOutParameter(paramNameToUse, meta));
436440
outParamNames.add(paramNameToUse);
437441
if (logger.isDebugEnabled()) {
438442
logger.debug("Added metadata out parameter for '" + paramNameToUse + "'");
439443
}
440444
}
441445
else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
442-
workParams.add(this.metaDataProvider.createDefaultInOutParameter(paramNameToUse, meta));
446+
workParams.add(provider.createDefaultInOutParameter(paramNameToUse, meta));
443447
outParamNames.add(paramNameToUse);
444448
if (logger.isDebugEnabled()) {
445449
logger.debug("Added metadata in out parameter for '" + paramNameToUse + "'");
@@ -448,7 +452,7 @@ else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
448452
else {
449453
if (this.limitedInParameterNames.isEmpty() ||
450454
limitedInParamNamesMap.containsKey(lowerCase(paramNameToUse))) {
451-
workParams.add(this.metaDataProvider.createDefaultInParameter(paramNameToUse, meta));
455+
workParams.add(provider.createDefaultInParameter(paramNameToUse, meta));
452456
if (logger.isDebugEnabled()) {
453457
logger.debug("Added metadata in parameter for '" + paramNameToUse + "'");
454458
}
@@ -473,8 +477,6 @@ else if (meta.getParameterType() == DatabaseMetaData.procedureColumnInOut) {
473477
* @return a Map containing the matched parameter names with the value taken from the input
474478
*/
475479
public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameterSource parameterSource) {
476-
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
477-
478480
// For parameter source lookups we need to provide case-insensitive lookup support
479481
// since the database metadata is not necessarily providing case sensitive parameter names.
480482
Map<String, String> caseInsensitiveParameterNames =
@@ -485,7 +487,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
485487
for (SqlParameter parameter : this.callParameters) {
486488
if (parameter.isInputValueProvided()) {
487489
String parameterName = parameter.getName();
488-
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
490+
String parameterNameToMatch = obtainMetaDataProvider().parameterNameToUse(parameterName);
489491
if (parameterNameToMatch != null) {
490492
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
491493
}
@@ -538,16 +540,16 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
538540
* @return a Map containing the matched parameter names with the value taken from the input
539541
*/
540542
public Map<String, ?> matchInParameterValuesWithCallParameters(Map<String, ?> inParameters) {
541-
Assert.state(this.metaDataProvider != null, "No CallMetaDataProvider available");
542-
if (!this.metaDataProvider.isProcedureColumnMetaDataUsed()) {
543+
CallMetaDataProvider provider = obtainMetaDataProvider();
544+
if (!provider.isProcedureColumnMetaDataUsed()) {
543545
return inParameters;
544546
}
545547

546548
Map<String, String> callParameterNames = new HashMap<>(this.callParameters.size());
547549
for (SqlParameter parameter : this.callParameters) {
548550
if (parameter.isInputValueProvided()) {
549551
String parameterName = parameter.getName();
550-
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
552+
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
551553
if (parameterNameToMatch != null) {
552554
callParameterNames.put(parameterNameToMatch.toLowerCase(), parameterName);
553555
}
@@ -556,7 +558,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
556558

557559
Map<String, Object> matchedParameters = new HashMap<>(inParameters.size());
558560
for (String parameterName : inParameters.keySet()) {
559-
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
561+
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
560562
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
561563
if (callParameterName == null) {
562564
if (logger.isDebugEnabled()) {
@@ -577,7 +579,7 @@ public Map<String, Object> matchInParameterValuesWithCallParameters(SqlParameter
577579

578580
if (matchedParameters.size() < callParameterNames.size()) {
579581
for (String parameterName : callParameterNames.keySet()) {
580-
String parameterNameToMatch = this.metaDataProvider.parameterNameToUse(parameterName);
582+
String parameterNameToMatch = provider.parameterNameToUse(parameterName);
581583
String callParameterName = callParameterNames.get(lowerCase(parameterNameToMatch));
582584
if (!matchedParameters.containsKey(callParameterName)) {
583585
logger.warn("Unable to locate the corresponding parameter value for '" + parameterName +

0 commit comments

Comments
 (0)