Introduce getBeanProvider variants with allowEagerInit flag
Closes gh-25559
This commit is contained in:
parent
392f51cdd6
commit
b345019415
|
@ -87,6 +87,43 @@ public interface ListableBeanFactory extends BeanFactory {
|
|||
*/
|
||||
String[] getBeanDefinitionNames();
|
||||
|
||||
/**
|
||||
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* @param requiredType type the bean must match; can be an interface or superclass
|
||||
* @param allowEagerInit whether stream-based access may initialize <i>lazy-init
|
||||
* singletons</i> and <i>objects created by FactoryBeans</i> (or by factory methods
|
||||
* with a "factory-bean" reference) for the type check
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.3
|
||||
* @see #getBeanProvider(ResolvableType, boolean)
|
||||
* @see #getBeanProvider(Class)
|
||||
* @see #getBeansOfType(Class, boolean, boolean)
|
||||
* @see #getBeanNamesForType(Class, boolean, boolean)
|
||||
*/
|
||||
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);
|
||||
|
||||
/**
|
||||
* Return a provider for the specified bean, allowing for lazy on-demand retrieval
|
||||
* of instances, including availability and uniqueness options.
|
||||
* @param requiredType type the bean must match; can be a generic type declaration.
|
||||
* Note that collection types are not supported here, in contrast to reflective
|
||||
* injection points. For programmatically retrieving a list of beans matching a
|
||||
* specific type, specify the actual bean type as an argument here and subsequently
|
||||
* use {@link ObjectProvider#orderedStream()} or its lazy streaming/iteration options.
|
||||
* @param allowEagerInit whether stream-based access may initialize <i>lazy-init
|
||||
* singletons</i> and <i>objects created by FactoryBeans</i> (or by factory methods
|
||||
* with a "factory-bean" reference) for the type check
|
||||
* @return a corresponding provider handle
|
||||
* @since 5.3
|
||||
* @see #getBeanProvider(ResolvableType)
|
||||
* @see ObjectProvider#iterator()
|
||||
* @see ObjectProvider#stream()
|
||||
* @see ObjectProvider#orderedStream()
|
||||
* @see #getBeanNamesForType(ResolvableType, boolean, boolean)
|
||||
*/
|
||||
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit);
|
||||
|
||||
/**
|
||||
* Return the names of beans matching the given type (including subclasses),
|
||||
* judging from either bean definitions or the value of {@code getObjectType}
|
||||
|
|
|
@ -354,14 +354,51 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) throws BeansException {
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) {
|
||||
Assert.notNull(requiredType, "Required type must not be null");
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType));
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
|
||||
return getBeanProvider(requiredType, true);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of ListableBeanFactory interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean containsBeanDefinition(String beanName) {
|
||||
Assert.notNull(beanName, "Bean name must not be null");
|
||||
return this.beanDefinitionMap.containsKey(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanDefinitionCount() {
|
||||
return this.beanDefinitionMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanDefinitionNames() {
|
||||
String[] frozenNames = this.frozenBeanDefinitionNames;
|
||||
if (frozenNames != null) {
|
||||
return frozenNames.clone();
|
||||
}
|
||||
else {
|
||||
return StringUtils.toStringArray(this.beanDefinitionNames);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
Assert.notNull(requiredType, "Required type must not be null");
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return new BeanObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
|
@ -426,14 +463,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
}
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType))
|
||||
return Arrays.stream(getBeanNamesForTypedStream(requiredType, allowEagerInit))
|
||||
.map(name -> (T) getBean(name))
|
||||
.filter(bean -> !(bean instanceof NullBean));
|
||||
}
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Stream<T> orderedStream() {
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType);
|
||||
String[] beanNames = getBeanNamesForTypedStream(requiredType, allowEagerInit);
|
||||
if (beanNames.length == 0) {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
@ -472,35 +511,8 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
|||
return null;
|
||||
}
|
||||
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType);
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Implementation of ListableBeanFactory interface
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
@Override
|
||||
public boolean containsBeanDefinition(String beanName) {
|
||||
Assert.notNull(beanName, "Bean name must not be null");
|
||||
return this.beanDefinitionMap.containsKey(beanName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getBeanDefinitionCount() {
|
||||
return this.beanDefinitionMap.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanDefinitionNames() {
|
||||
String[] frozenNames = this.frozenBeanDefinitionNames;
|
||||
if (frozenNames != null) {
|
||||
return frozenNames.clone();
|
||||
}
|
||||
else {
|
||||
return StringUtils.toStringArray(this.beanDefinitionNames);
|
||||
}
|
||||
private String[] getBeanNamesForTypedStream(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this, requiredType, true, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -186,73 +186,12 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
|||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType) throws BeansException {
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType));
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), true);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType) {
|
||||
return new ObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public T getObject(Object... args) throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], args);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForType(requiredType)).map(name -> (T) getBean(name));
|
||||
}
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
return stream().sorted(OrderComparator.INSTANCE);
|
||||
}
|
||||
};
|
||||
return getBeanProvider(requiredType, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -337,6 +276,77 @@ public class StaticListableBeanFactory implements ListableBeanFactory {
|
|||
return StringUtils.toStringArray(this.beans.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
return getBeanProvider(ResolvableType.forRawClass(requiredType), allowEagerInit);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return new ObjectProvider<T>() {
|
||||
@Override
|
||||
public T getObject() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], requiredType);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public T getObject(Object... args) throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0], args);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
throw new NoSuchBeanDefinitionException(requiredType);
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfAvailable() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else if (beanNames.length > 1) {
|
||||
throw new NoUniqueBeanDefinitionException(requiredType, beanNames);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
@Nullable
|
||||
public T getIfUnique() throws BeansException {
|
||||
String[] beanNames = getBeanNamesForType(requiredType);
|
||||
if (beanNames.length == 1) {
|
||||
return (T) getBean(beanNames[0]);
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public Stream<T> stream() {
|
||||
return Arrays.stream(getBeanNamesForType(requiredType)).map(name -> (T) getBean(name));
|
||||
}
|
||||
@Override
|
||||
public Stream<T> orderedStream() {
|
||||
return stream().sorted(OrderComparator.INSTANCE);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
|
||||
return getBeanNamesForType(type, true, true);
|
||||
|
|
|
@ -1263,6 +1263,18 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader
|
|||
return getBeanFactory().getBeanDefinitionNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
assertBeanFactoryActive();
|
||||
return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
assertBeanFactoryActive();
|
||||
return getBeanFactory().getBeanProvider(requiredType, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanNamesForType(ResolvableType type) {
|
||||
assertBeanFactoryActive();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2002-2019 the original author or authors.
|
||||
* 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.
|
||||
|
@ -252,6 +252,16 @@ class StubWebApplicationContext implements WebApplicationContext {
|
|||
return this.beanFactory.getBeanDefinitionNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit) {
|
||||
return this.beanFactory.getBeanProvider(requiredType, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType, boolean allowEagerInit) {
|
||||
return this.beanFactory.getBeanProvider(requiredType, allowEagerInit);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getBeanNamesForType(@Nullable ResolvableType type) {
|
||||
return this.beanFactory.getBeanNamesForType(type);
|
||||
|
|
Loading…
Reference in New Issue