diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java index 9f5a503634..13c03732b8 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java @@ -40,6 +40,8 @@ import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import java.util.function.Consumer; +import java.util.function.Predicate; import java.util.stream.Stream; import javax.inject.Provider; @@ -946,18 +948,14 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; - if (this.manualSingletonNames.contains(beanName)) { - Set updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); - updatedSingletons.remove(beanName); - this.manualSingletonNames = updatedSingletons; - } + removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); - this.manualSingletonNames.remove(beanName); + removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } @@ -1045,42 +1043,53 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto @Override public void registerSingleton(String beanName, Object singletonObject) throws IllegalStateException { super.registerSingleton(beanName, singletonObject); - - if (hasBeanCreationStarted()) { - // Cannot modify startup-time collection elements anymore (for stable iteration) - synchronized (this.beanDefinitionMap) { - if (!this.beanDefinitionMap.containsKey(beanName)) { - Set updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames.size() + 1); - updatedSingletons.addAll(this.manualSingletonNames); - updatedSingletons.add(beanName); - this.manualSingletonNames = updatedSingletons; - } - } - } - else { - // Still in startup registration phase - if (!this.beanDefinitionMap.containsKey(beanName)) { - this.manualSingletonNames.add(beanName); - } - } - - clearByTypeCache(); - } - - @Override - public void destroySingleton(String beanName) { - super.destroySingleton(beanName); - this.manualSingletonNames.remove(beanName); + updateManualSingletonNames(set -> set.add(beanName), set -> !this.beanDefinitionMap.containsKey(beanName)); clearByTypeCache(); } @Override public void destroySingletons() { super.destroySingletons(); - this.manualSingletonNames.clear(); + updateManualSingletonNames(Set::clear, set -> !set.isEmpty()); clearByTypeCache(); } + @Override + public void destroySingleton(String beanName) { + super.destroySingleton(beanName); + removeManualSingletonName(beanName); + clearByTypeCache(); + } + + private void removeManualSingletonName(String beanName) { + updateManualSingletonNames(set -> set.remove(beanName), set -> set.contains(beanName)); + } + + /** + * Update the factory's internal set of manual singleton names. + * @param action the modification action + * @param condition a precondition for the modification action + * (if this condition does not apply, the action can be skipped) + */ + private void updateManualSingletonNames(Consumer> action, Predicate> condition) { + if (hasBeanCreationStarted()) { + // Cannot modify startup-time collection elements anymore (for stable iteration) + synchronized (this.beanDefinitionMap) { + if (condition.test(this.manualSingletonNames)) { + Set updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames); + action.accept(updatedSingletons); + this.manualSingletonNames = updatedSingletons; + } + } + } + else { + // Still in startup registration phase + if (condition.test(this.manualSingletonNames)) { + action.accept(this.manualSingletonNames); + } + } + } + /** * Remove any assumptions about by-type mappings. */ diff --git a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java index 25f59c1e64..a7409e6f11 100644 --- a/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java +++ b/spring-messaging/src/main/java/org/springframework/messaging/handler/invocation/InvocableHandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -147,11 +147,11 @@ public class InvocableHandlerMethod extends HandlerMethod { args[i] = this.resolvers.resolveArgument(parameter, message); } catch (Exception ex) { - // Leave stack trace for later, exception may actually be resolved and handled.. + // Leave stack trace for later, exception may actually be resolved and handled... if (logger.isDebugEnabled()) { - String error = ex.getMessage(); - if (error != null && !error.contains(parameter.getExecutable().toGenericString())) { - logger.debug(formatArgumentError(parameter, error)); + String exMsg = ex.getMessage(); + if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { + logger.debug(formatArgumentError(parameter, exMsg)); } } throw ex; diff --git a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java index 1426e0f94a..37eef7ada0 100644 --- a/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java +++ b/spring-web/src/main/java/org/springframework/web/method/support/InvocableHandlerMethod.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2019 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -166,11 +166,11 @@ public class InvocableHandlerMethod extends HandlerMethod { args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory); } catch (Exception ex) { - // Leave stack trace for later, exception may actually be resolved and handled.. + // Leave stack trace for later, exception may actually be resolved and handled... if (logger.isDebugEnabled()) { - String error = ex.getMessage(); - if (error != null && !error.contains(parameter.getExecutable().toGenericString())) { - logger.debug(formatArgumentError(parameter, error)); + String exMsg = ex.getMessage(); + if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { + logger.debug(formatArgumentError(parameter, exMsg)); } } throw ex; diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java index f1ac283d65..a65dd960e5 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/result/method/InvocableHandlerMethod.java @@ -200,7 +200,7 @@ public class InvocableHandlerMethod extends HandlerMethod { try { argMonos.add(this.resolvers.resolveArgument(parameter, bindingContext, exchange) .defaultIfEmpty(NO_ARG_VALUE) - .doOnError(cause -> logArgumentErrorIfNecessary(exchange, parameter, cause))); + .doOnError(ex -> logArgumentErrorIfNecessary(exchange, parameter, ex))); } catch (Exception ex) { logArgumentErrorIfNecessary(exchange, parameter, ex); @@ -211,14 +211,12 @@ public class InvocableHandlerMethod extends HandlerMethod { Stream.of(values).map(o -> o != NO_ARG_VALUE ? o : null).toArray()); } - private void logArgumentErrorIfNecessary( - ServerWebExchange exchange, MethodParameter parameter, Throwable cause) { - - // Leave stack trace for later, if error is not handled.. - String message = cause.getMessage(); - if (message != null && !message.contains(parameter.getExecutable().toGenericString())) { + private void logArgumentErrorIfNecessary(ServerWebExchange exchange, MethodParameter parameter, Throwable ex) { + // Leave stack trace for later, if error is not handled... + String exMsg = ex.getMessage(); + if (exMsg != null && !exMsg.contains(parameter.getExecutable().toGenericString())) { if (logger.isDebugEnabled()) { - logger.debug(exchange.getLogPrefix() + formatArgumentError(parameter, message)); + logger.debug(exchange.getLogPrefix() + formatArgumentError(parameter, exMsg)); } } }