Add public method to get bean order on DefaultListableBeanFactory
Closes gh-34712
This commit is contained in:
parent
c5da405314
commit
841d9fb73b
|
@ -29,6 +29,7 @@ import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -2315,6 +2316,33 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
return (result instanceof Optional<?> optional ? optional : Optional.ofNullable(result));
|
return (result instanceof Optional<?> optional ? optional : Optional.ofNullable(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public method to determine the applicable order value for a given bean.
|
||||||
|
* <p>This variant implicitly obtains a corresponding bean instance from this factory.
|
||||||
|
* @param beanName the name of the bean
|
||||||
|
* @return the corresponding order value (default is {@link Ordered#LOWEST_PRECEDENCE})
|
||||||
|
* @since 7.0
|
||||||
|
* @see #getOrder(String, Object)
|
||||||
|
*/
|
||||||
|
public int getOrder(String beanName) {
|
||||||
|
return getOrder(beanName, getBean(beanName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Public method to determine the applicable order value for a given bean.
|
||||||
|
* @param beanName the name of the bean
|
||||||
|
* @param beanInstance the bean instance to check
|
||||||
|
* @return the corresponding order value (default is {@link Ordered#LOWEST_PRECEDENCE})
|
||||||
|
* @since 7.0
|
||||||
|
* @see #getOrder(String)
|
||||||
|
*/
|
||||||
|
public int getOrder(String beanName, Object beanInstance) {
|
||||||
|
OrderComparator comparator = (getDependencyComparator() instanceof OrderComparator orderComparator ?
|
||||||
|
orderComparator : OrderComparator.INSTANCE);
|
||||||
|
return comparator.getOrder(beanInstance,
|
||||||
|
new FactoryAwareOrderSourceProvider(Collections.singletonMap(beanInstance, beanName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
@ -2672,7 +2700,7 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
RootBeanDefinition beanDefinition = (RootBeanDefinition) getMergedBeanDefinition(beanName);
|
BeanDefinition beanDefinition = getMergedBeanDefinition(beanName);
|
||||||
List<Object> sources = new ArrayList<>(3);
|
List<Object> sources = new ArrayList<>(3);
|
||||||
Object orderAttribute = beanDefinition.getAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE);
|
Object orderAttribute = beanDefinition.getAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE);
|
||||||
if (orderAttribute != null) {
|
if (orderAttribute != null) {
|
||||||
|
@ -2684,14 +2712,16 @@ public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFacto
|
||||||
AbstractBeanDefinition.ORDER_ATTRIBUTE + "': " + orderAttribute.getClass().getName());
|
AbstractBeanDefinition.ORDER_ATTRIBUTE + "': " + orderAttribute.getClass().getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Method factoryMethod = beanDefinition.getResolvedFactoryMethod();
|
if (beanDefinition instanceof RootBeanDefinition rootBeanDefinition) {
|
||||||
|
Method factoryMethod = rootBeanDefinition.getResolvedFactoryMethod();
|
||||||
if (factoryMethod != null) {
|
if (factoryMethod != null) {
|
||||||
sources.add(factoryMethod);
|
sources.add(factoryMethod);
|
||||||
}
|
}
|
||||||
Class<?> targetType = beanDefinition.getTargetType();
|
Class<?> targetType = rootBeanDefinition.getTargetType();
|
||||||
if (targetType != null && targetType != obj.getClass()) {
|
if (targetType != null && targetType != obj.getClass()) {
|
||||||
sources.add(targetType);
|
sources.add(targetType);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return sources.toArray();
|
return sources.toArray();
|
||||||
}
|
}
|
||||||
catch (NoSuchBeanDefinitionException ex) {
|
catch (NoSuchBeanDefinitionException ex) {
|
||||||
|
|
|
@ -1542,6 +1542,7 @@ class DefaultListableBeanFactoryTests {
|
||||||
bd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE);
|
bd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.HIGHEST_PRECEDENCE);
|
||||||
bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
bd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||||
lbf.registerBeanDefinition("bean2", bd2);
|
lbf.registerBeanDefinition("bean2", bd2);
|
||||||
|
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
||||||
.containsExactly("highest", "lowest");
|
.containsExactly("highest", "lowest");
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(clazz -> !DerivedTestBean.class.isAssignableFrom(clazz))
|
||||||
|
@ -1550,6 +1551,9 @@ class DefaultListableBeanFactoryTests {
|
||||||
.containsExactly("highest", "lowest");
|
.containsExactly("highest", "lowest");
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
||||||
.containsExactly("lowest");
|
.containsExactly("lowest");
|
||||||
|
|
||||||
|
assertThat(lbf.getOrder("bean1")).isEqualTo(Ordered.LOWEST_PRECEDENCE);
|
||||||
|
assertThat(lbf.getOrder("bean2")).isEqualTo(Ordered.HIGHEST_PRECEDENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1562,12 +1566,16 @@ class DefaultListableBeanFactoryTests {
|
||||||
rbd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.LOWEST_PRECEDENCE);
|
rbd2.setAttribute(AbstractBeanDefinition.ORDER_ATTRIBUTE, Ordered.LOWEST_PRECEDENCE);
|
||||||
rbd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
rbd2.setScope(BeanDefinition.SCOPE_PROTOTYPE);
|
||||||
lbf.registerBeanDefinition("highestPrecedenceFactory", rbd2);
|
lbf.registerBeanDefinition("highestPrecedenceFactory", rbd2);
|
||||||
|
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream().map(TestBean::getName))
|
||||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED).map(TestBean::getName))
|
||||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean", "fromHighestPrecedenceTestBeanFactoryBean");
|
||||||
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
assertThat(lbf.getBeanProvider(TestBean.class).orderedStream(ObjectProvider.UNFILTERED, false).map(TestBean::getName))
|
||||||
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean");
|
.containsExactly("fromLowestPrecedenceTestBeanFactoryBean");
|
||||||
|
|
||||||
|
assertThat(lbf.getOrder("lowestPrecedenceFactory")).isEqualTo(Ordered.HIGHEST_PRECEDENCE);
|
||||||
|
assertThat(lbf.getOrder("highestPrecedenceFactory")).isEqualTo(Ordered.LOWEST_PRECEDENCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -1579,6 +1587,7 @@ class DefaultListableBeanFactoryTests {
|
||||||
GenericBeanDefinition bd2 = new GenericBeanDefinition();
|
GenericBeanDefinition bd2 = new GenericBeanDefinition();
|
||||||
bd2.setBeanClass(TestBean.class);
|
bd2.setBeanClass(TestBean.class);
|
||||||
lbf.registerBeanDefinition("bean", bd2);
|
lbf.registerBeanDefinition("bean", bd2);
|
||||||
|
|
||||||
assertThatIllegalStateException()
|
assertThatIllegalStateException()
|
||||||
.isThrownBy(() -> lbf.getBeanProvider(TestBean.class).orderedStream().collect(Collectors.toList()))
|
.isThrownBy(() -> lbf.getBeanProvider(TestBean.class).orderedStream().collect(Collectors.toList()))
|
||||||
.withMessageContaining("Invalid value type for attribute");
|
.withMessageContaining("Invalid value type for attribute");
|
||||||
|
|
|
@ -44,6 +44,9 @@ class Gh29105Tests {
|
||||||
Stream<Class<?>> orderedTypes = child.getBeanProvider(MyService.class).orderedStream().map(Object::getClass);
|
Stream<Class<?>> orderedTypes = child.getBeanProvider(MyService.class).orderedStream().map(Object::getClass);
|
||||||
assertThat(orderedTypes).containsExactly(CustomService.class, DefaultService.class);
|
assertThat(orderedTypes).containsExactly(CustomService.class, DefaultService.class);
|
||||||
|
|
||||||
|
assertThat(child.getDefaultListableBeanFactory().getOrder("defaultService")).isEqualTo(0);
|
||||||
|
assertThat(child.getDefaultListableBeanFactory().getOrder("customService")).isEqualTo(-1);
|
||||||
|
|
||||||
child.close();
|
child.close();
|
||||||
parent.close();
|
parent.close();
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,8 +95,9 @@ public class OrderComparator implements Comparator<Object> {
|
||||||
* using {@link #findOrder} and falls back to a regular {@link #getOrder(Object)} call.
|
* using {@link #findOrder} and falls back to a regular {@link #getOrder(Object)} call.
|
||||||
* @param obj the object to check
|
* @param obj the object to check
|
||||||
* @return the order value, or {@code Ordered.LOWEST_PRECEDENCE} as fallback
|
* @return the order value, or {@code Ordered.LOWEST_PRECEDENCE} as fallback
|
||||||
|
* @since 7.0
|
||||||
*/
|
*/
|
||||||
private int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
|
public int getOrder(@Nullable Object obj, @Nullable OrderSourceProvider sourceProvider) {
|
||||||
Integer order = null;
|
Integer order = null;
|
||||||
if (obj != null && sourceProvider != null) {
|
if (obj != null && sourceProvider != null) {
|
||||||
Object orderSource = sourceProvider.getOrderSource(obj);
|
Object orderSource = sourceProvider.getOrderSource(obj);
|
||||||
|
|
Loading…
Reference in New Issue