Gracefully ignore placeholder exceptions

Update BeanTypeRegistry to gracefully ignore LoadBeanClassException and
BeanDefinitionStoreException exceptions in the same way as
DefaultListableBeanFactory.doGetBeanNamesForType() does.

Fixes gh-1955
This commit is contained in:
Phillip Webb
2014-11-19 09:57:52 -08:00
parent 7fa0ea7c3b
commit 3a4d62fb3a
2 changed files with 60 additions and 1 deletions

View File

@@ -24,8 +24,12 @@ import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.CannotLoadBeanClassException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.SmartInitializingSingleton;
@@ -54,7 +58,7 @@ import org.springframework.util.StringUtils;
*/
abstract class BeanTypeRegistry {
public static long check;
static Log logger = LogFactory.getLog(BeanTypeRegistry.class);
static final String FACTORY_BEAN_OBJECT_TYPE = "factoryBeanObjectType";
@@ -239,6 +243,12 @@ abstract class BeanTypeRegistry {
this.beanTypes.put(name, this.beanFactory.getType(name));
}
else if (!this.beanFactory.isAlias(name)) {
addBeanTypeForNonAliasDefinition(name);
}
}
private void addBeanTypeForNonAliasDefinition(String name) {
try {
String factoryName = BeanFactory.FACTORY_BEAN_PREFIX + name;
RootBeanDefinition beanDefinition = (RootBeanDefinition) this.beanFactory
.getMergedBeanDefinition(name);
@@ -256,6 +266,21 @@ abstract class BeanTypeRegistry {
}
}
}
catch (CannotLoadBeanClassException ex) {
// Probably contains a placeholder
logIgnoredError("bean class loading failure for bean", name, ex);
}
catch (BeanDefinitionStoreException ex) {
// Probably contains a placeholder
logIgnoredError("unresolvable metadata in bean definition", name, ex);
}
}
private void logIgnoredError(String message, String name, Exception ex) {
if (BeanTypeRegistry.logger.isDebugEnabled()) {
BeanTypeRegistry.logger.debug("Ignoring " + message + " '" + name + "'",
ex);
}
}
private boolean requiresEagerInit(String factoryBeanName) {

View File

@@ -19,11 +19,17 @@ package org.springframework.boot.autoconfigure.condition;
import java.util.Date;
import org.junit.Test;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.boot.test.EnvironmentTestUtils;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.context.annotation.ImportResource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.scheduling.annotation.EnableScheduling;
import static org.junit.Assert.assertEquals;
@@ -116,6 +122,14 @@ public class ConditionalOnBeanTests {
assertFalse(this.context.containsBean("bar"));
}
@Test
public void withPropertyPlaceholderClassName() throws Exception {
EnvironmentTestUtils.addEnvironment(this.context, "mybeanclass=java.lang.String");
this.context.register(PropertySourcesPlaceholderConfigurer.class,
WithPropertyPlaceholderClassName.class, OnBeanClassConfiguration.class);
this.context.refresh();
}
@Configuration
@ConditionalOnBean(name = "foo")
protected static class OnBeanNameConfiguration {
@@ -189,4 +203,24 @@ public class ConditionalOnBeanTests {
@Import(OnBeanNameConfiguration.class)
protected static class CombinedXmlConfiguration {
}
@Configuration
@Import(WithPropertyPlaceholderClassNameRegistrar.class)
protected static class WithPropertyPlaceholderClassName {
}
protected static class WithPropertyPlaceholderClassNameRegistrar implements
ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
RootBeanDefinition bd = new RootBeanDefinition();
bd.setBeanClassName("${mybeanclass}");
registry.registerBeanDefinition("mybean", bd);
}
}
}