From f26866e4d444288a748df3358839f00ee90d5216 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 4 Sep 2019 00:06:23 +0200 Subject: [PATCH] Introduce getType variant with allowFactoryBeanInit flag Closes gh-23374 --- .../beans/factory/BeanFactory.java | 24 ++++++++++++++++++- .../factory/support/AbstractBeanFactory.java | 15 ++++++++---- .../support/StaticListableBeanFactory.java | 5 ++++ .../support/AbstractApplicationContext.java | 7 ++++++ .../jndi/support/SimpleJndiBeanFactory.java | 6 +++++ .../setup/StubWebApplicationContext.java | 5 ++++ 6 files changed, 56 insertions(+), 6 deletions(-) diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java index 583f2daf3d..e0b345f622 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/BeanFactory.java @@ -323,7 +323,8 @@ public interface BeanFactory { * Determine the type of the bean with the given name. More specifically, * determine the type of object that {@link #getBean} would return for the given name. *

For a {@link FactoryBean}, return the type of object that the FactoryBean creates, - * as exposed by {@link FactoryBean#getObjectType()}. + * as exposed by {@link FactoryBean#getObjectType()}. This may lead to the initialization + * of a previously uninitialized {@code FactoryBean} (see {@link #getType(String, boolean)}). *

Translates aliases back to the corresponding canonical bean name. * Will ask the parent factory if the bean cannot be found in this factory instance. * @param name the name of the bean to query @@ -336,6 +337,27 @@ public interface BeanFactory { @Nullable Class getType(String name) throws NoSuchBeanDefinitionException; + /** + * Determine the type of the bean with the given name. More specifically, + * determine the type of object that {@link #getBean} would return for the given name. + *

For a {@link FactoryBean}, return the type of object that the FactoryBean creates, + * as exposed by {@link FactoryBean#getObjectType()}. Depending on the + * {@code allowFactoryBeanInit} flag, this may lead to the initialization of a previously + * uninitialized {@code FactoryBean} if no early type information is available. + *

Translates aliases back to the corresponding canonical bean name. + * Will ask the parent factory if the bean cannot be found in this factory instance. + * @param name the name of the bean to query + * @param allowFactoryBeanInit whether a {@code FactoryBean} may get initialized + * just for the purpose of determining its object type + * @return the type of the bean, or {@code null} if not determinable + * @throws NoSuchBeanDefinitionException if there is no bean with the given name + * @since 5.2 + * @see #getBean + * @see #isTypeMatch + */ + @Nullable + Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; + /** * Return the aliases for the given bean name, if any. * All of those aliases point to the same bean when used in a {@link #getBean} call. diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java index 343c9418f4..d67a8e3f3d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/AbstractBeanFactory.java @@ -502,14 +502,13 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp * {@code ResolvableType}) * @return {@code true} if the bean type matches, {@code false} if it * doesn't match or cannot be determined yet - * @throws NoSuchBeanDefinitionException if there is no bean with the given - * name + * @throws NoSuchBeanDefinitionException if there is no bean with the given name * @since 5.2 * @see #getBean * @see #getType */ - boolean isTypeMatch(String name, ResolvableType typeToMatch, - boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { + protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit) + throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name); @@ -657,6 +656,12 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp @Override @Nullable public Class getType(String name) throws NoSuchBeanDefinitionException { + return getType(name, true); + } + + @Override + @Nullable + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); // Check manually registered singletons. @@ -696,7 +701,7 @@ public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport imp if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { if (!BeanFactoryUtils.isFactoryDereference(name)) { // If it's a FactoryBean, we want to look at what it creates, not at the factory class. - return getTypeForFactoryBean(beanName, mbd, true).resolve(); + return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve(); } else { return beanClass; diff --git a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java index ee364317e3..7d77a45b0d 100644 --- a/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java +++ b/spring-beans/src/main/java/org/springframework/beans/factory/support/StaticListableBeanFactory.java @@ -287,6 +287,11 @@ public class StaticListableBeanFactory implements ListableBeanFactory { @Override public Class getType(String name) throws NoSuchBeanDefinitionException { + return getType(name, true); + } + + @Override + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { String beanName = BeanFactoryUtils.transformedBeanName(name); Object bean = this.beans.get(beanName); diff --git a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java index aa46bb8653..b707f0df05 100644 --- a/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java +++ b/spring-context/src/main/java/org/springframework/context/support/AbstractApplicationContext.java @@ -1177,6 +1177,13 @@ public abstract class AbstractApplicationContext extends DefaultResourceLoader return getBeanFactory().getType(name); } + @Override + @Nullable + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { + assertBeanFactoryActive(); + return getBeanFactory().getType(name, allowFactoryBeanInit); + } + @Override public String[] getAliases(String name) { return getBeanFactory().getAliases(name); diff --git a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java index 13b0f751d7..0224a833cc 100644 --- a/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java +++ b/spring-context/src/main/java/org/springframework/jndi/support/SimpleJndiBeanFactory.java @@ -234,6 +234,12 @@ public class SimpleJndiBeanFactory extends JndiLocatorSupport implements BeanFac @Override @Nullable public Class getType(String name) throws NoSuchBeanDefinitionException { + return getType(name, true); + } + + @Override + @Nullable + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { try { return doGetType(name); } diff --git a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java index e86bd75ed5..4ab6f1b5bb 100644 --- a/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java +++ b/spring-test/src/main/java/org/springframework/test/web/servlet/setup/StubWebApplicationContext.java @@ -221,6 +221,11 @@ class StubWebApplicationContext implements WebApplicationContext { return this.beanFactory.getType(name); } + @Override + public Class getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException { + return this.beanFactory.getType(name, allowFactoryBeanInit); + } + @Override public String[] getAliases(String name) { return this.beanFactory.getAliases(name);