mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-09-03 04:26:12 +08:00
Support String values for factoryBeanObjectType attribute on bean def
To allow us to determine the type that Spring Integration’s GatewayProxyFactoryBean will create, the bean definition created by MessagingGatewayRegistrar needs to set the factoryBeanObjectType attribute. The current implementation of BeanTypeRegistry requires the attribute’s value to be a Class, however this would require Spring Integration’s namespace handler to load the class and class loading should be avoided in namespace handlers. This commit updates BeanTypeRegistry so that it supports both Class and String values for the factoryBeanObjectType. If the value is a String it will interpret it as a class name and attempt to load it. See gh-2811
This commit is contained in:
parent
ebb8d0c55f
commit
337673b31d
@ -54,6 +54,7 @@ import org.springframework.util.StringUtils;
|
||||
* </ul>
|
||||
*
|
||||
* @author Phillip Webb
|
||||
* @author Andy Wilkinson
|
||||
* @since 1.2.0
|
||||
*/
|
||||
abstract class BeanTypeRegistry {
|
||||
@ -115,13 +116,26 @@ abstract class BeanTypeRegistry {
|
||||
definition.getFactoryMethodName());
|
||||
Class<?> generic = ResolvableType.forMethodReturnType(method)
|
||||
.as(FactoryBean.class).resolveGeneric();
|
||||
if ((generic == null || generic.equals(Object.class))
|
||||
&& definition.hasAttribute(FACTORY_BEAN_OBJECT_TYPE)) {
|
||||
generic = (Class<?>) definition.getAttribute(FACTORY_BEAN_OBJECT_TYPE);
|
||||
if (generic == null || generic.equals(Object.class)) {
|
||||
generic = determineTypeFromDefinitionAttribute(factoryDefinition);
|
||||
}
|
||||
return generic;
|
||||
}
|
||||
|
||||
private Class<?> determineTypeFromDefinitionAttribute(BeanDefinition definition)
|
||||
throws ClassNotFoundException, LinkageError {
|
||||
if (definition.hasAttribute(FACTORY_BEAN_OBJECT_TYPE)) {
|
||||
Object attributeObject = definition.getAttribute(FACTORY_BEAN_OBJECT_TYPE);
|
||||
if (attributeObject instanceof Class<?>) {
|
||||
return (Class<?>) attributeObject;
|
||||
}
|
||||
else if (attributeObject instanceof String) {
|
||||
return ClassUtils.forName((String) attributeObject, null);
|
||||
}
|
||||
}
|
||||
return Object.class;
|
||||
}
|
||||
|
||||
private Class<?> getDirectFactoryBeanGeneric(
|
||||
ConfigurableListableBeanFactory beanFactory, BeanDefinition definition,
|
||||
String name) throws ClassNotFoundException, LinkageError {
|
||||
@ -129,9 +143,8 @@ abstract class BeanTypeRegistry {
|
||||
beanFactory.getBeanClassLoader());
|
||||
Class<?> generic = ResolvableType.forClass(factoryBeanClass)
|
||||
.as(FactoryBean.class).resolveGeneric();
|
||||
if ((generic == null || generic.equals(Object.class))
|
||||
&& definition.hasAttribute(FACTORY_BEAN_OBJECT_TYPE)) {
|
||||
generic = (Class<?>) definition.getAttribute(FACTORY_BEAN_OBJECT_TYPE);
|
||||
if (generic == null || generic.equals(Object.class)) {
|
||||
generic = determineTypeFromDefinitionAttribute(definition);
|
||||
}
|
||||
return generic;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2013 the original author or authors.
|
||||
* Copyright 2012-2015 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.
|
||||
@ -43,6 +43,7 @@ import static org.junit.Assert.assertTrue;
|
||||
* @author Dave Syer
|
||||
* @author Phillip Webb
|
||||
* @author Jakub Kubrynski
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
@SuppressWarnings("resource")
|
||||
public class ConditionalOnMissingBeanTests {
|
||||
@ -157,8 +158,18 @@ public class ConditionalOnMissingBeanTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithNonspecificFactoryBean() {
|
||||
this.context.register(NonspecificFactoryBeanConfiguration.class,
|
||||
public void testOnMissingBeanConditionWithNonspecificFactoryBeanWithClassAttribute() {
|
||||
this.context.register(NonspecificFactoryBeanClassAttributeConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
assertThat(this.context.getBean(ExampleBean.class).toString(),
|
||||
equalTo("fromFactory"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testOnMissingBeanConditionWithNonspecificFactoryBeanWithStringAttribute() {
|
||||
this.context.register(NonspecificFactoryBeanStringAttributeConfiguration.class,
|
||||
ConditionalOnFactoryBean.class,
|
||||
PropertyPlaceholderAutoConfiguration.class);
|
||||
this.context.refresh();
|
||||
@ -211,11 +222,11 @@ public class ConditionalOnMissingBeanTests {
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(NonspecificFactoryBeanRegistrar.class)
|
||||
protected static class NonspecificFactoryBeanConfiguration {
|
||||
@Import(NonspecificFactoryBeanClassAttributeRegistrar.class)
|
||||
protected static class NonspecificFactoryBeanClassAttributeConfiguration {
|
||||
}
|
||||
|
||||
protected static class NonspecificFactoryBeanRegistrar implements
|
||||
protected static class NonspecificFactoryBeanClassAttributeRegistrar implements
|
||||
ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
@ -232,6 +243,29 @@ public class ConditionalOnMissingBeanTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(NonspecificFactoryBeanClassAttributeRegistrar.class)
|
||||
protected static class NonspecificFactoryBeanStringAttributeConfiguration {
|
||||
}
|
||||
|
||||
protected static class NonspecificFactoryBeanStringAttributeRegistrar implements
|
||||
ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata meta,
|
||||
BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(NonspecificFactoryBean.class);
|
||||
builder.addConstructorArgValue("foo");
|
||||
builder.getBeanDefinition()
|
||||
.setAttribute(OnBeanCondition.FACTORY_BEAN_OBJECT_TYPE,
|
||||
ExampleBean.class.getName());
|
||||
registry.registerBeanDefinition("exampleBeanFactoryBean",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@Import(FactoryBeanRegistrar.class)
|
||||
protected static class RegisteredFactoryBeanConfiguration {
|
||||
|
Loading…
Reference in New Issue
Block a user