Ignore resolved bean from non-active scope in getIfAvailable/getIfUnique
Closes gh-24822
This commit is contained in:
@@ -350,6 +350,9 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
|
||||
else {
|
||||
String scopeName = mbd.getScope();
|
||||
if (!StringUtils.hasLength(scopeName)) {
|
||||
throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");
|
||||
}
|
||||
final Scope scope = this.scopes.get(scopeName);
|
||||
if (scope == null) {
|
||||
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
|
||||
@@ -367,10 +370,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp
|
||||
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
|
||||
}
|
||||
catch (IllegalStateException ex) {
|
||||
throw new BeanCreationException(beanName,
|
||||
"Scope '" + scopeName + "' is not active for the current thread; consider " +
|
||||
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
|
||||
ex);
|
||||
throw new ScopeNotActiveException(beanName, scopeName, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -384,12 +384,48 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
return resolveBean(requiredType, null, false);
|
||||
try {
|
||||
return resolveBean(requiredType, null, false);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ifAvailable(Consumer<T> dependencyConsumer) throws BeansException {
|
||||
T dependency = getIfAvailable();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
return resolveBean(requiredType, null, true);
|
||||
try {
|
||||
return resolveBean(requiredType, null, true);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public void ifUnique(Consumer<T> dependencyConsumer) throws BeansException {
|
||||
T dependency = getIfUnique();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
@@ -1925,17 +1961,36 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
@Override
|
||||
@Nullable
|
||||
public Object getIfAvailable() throws BeansException {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
try {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(this.descriptor, this.beanName);
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
DependencyDescriptor descriptorToUse = new DependencyDescriptor(this.descriptor) {
|
||||
@Override
|
||||
public boolean isRequired() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ifAvailable(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||
Object dependency = getIfAvailable();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1953,11 +2008,30 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||
return null;
|
||||
}
|
||||
};
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||
try {
|
||||
if (this.optional) {
|
||||
return createOptionalDependency(descriptorToUse, this.beanName);
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
}
|
||||
}
|
||||
else {
|
||||
return doResolveDependency(descriptorToUse, this.beanName, null, null);
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ifUnique(Consumer<Object> dependencyConsumer) throws BeansException {
|
||||
Object dependency = getIfUnique();
|
||||
if (dependency != null) {
|
||||
try {
|
||||
dependencyConsumer.accept(dependency);
|
||||
}
|
||||
catch (ScopeNotActiveException ex) {
|
||||
// Ignore resolved bean in non-active scope, even on scoped proxy invocation
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright 2002-2020 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.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.beans.factory.support;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
|
||||
/**
|
||||
* A subclass of {@link BeanCreationException} which indicates that the target scope
|
||||
* is not active, e.g. in case of request or session scope.
|
||||
*
|
||||
* @author Juergen Hoeller
|
||||
* @since 5.3
|
||||
* @see org.springframework.beans.factory.BeanFactory#getBean
|
||||
* @see org.springframework.beans.factory.config.Scope
|
||||
* @see AbstractBeanDefinition#setScope
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class ScopeNotActiveException extends BeanCreationException {
|
||||
|
||||
/**
|
||||
* Create a new ScopeNotActiveException.
|
||||
* @param beanName the name of the bean requested
|
||||
* @param scopeName the name of the target scope
|
||||
* @param cause the root cause, typically from {@link org.springframework.beans.factory.config.Scope#get}
|
||||
*/
|
||||
public ScopeNotActiveException(String beanName, String scopeName, IllegalStateException cause) {
|
||||
super(beanName, "Scope '" + scopeName + "' is not active for the current thread; consider " +
|
||||
"defining a scoped proxy for this bean if you intend to refer to it from a singleton", cause);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user