Skip to content

Commit c6d29f1

Browse files
committed
Refactored support for @order on @bean methods as well as @priority handling
Issue: SPR-11310 Issue: SPR-10548
1 parent 82f8b43 commit c6d29f1

File tree

17 files changed

+281
-661
lines changed

17 files changed

+281
-661
lines changed

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultDependencyComparator.java

Lines changed: 0 additions & 61 deletions
This file was deleted.

spring-beans/src/main/java/org/springframework/beans/factory/support/DefaultListableBeanFactory.java

Lines changed: 52 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.lang.annotation.Annotation;
2525
import java.lang.ref.Reference;
2626
import java.lang.ref.WeakReference;
27+
import java.lang.reflect.Method;
2728
import java.security.AccessController;
2829
import java.security.PrivilegedAction;
2930
import java.util.ArrayList;
@@ -62,9 +63,8 @@
6263
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
6364
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
6465
import org.springframework.beans.factory.config.DependencyDescriptor;
66+
import org.springframework.core.OrderComparator;
6567
import org.springframework.core.annotation.AnnotationUtils;
66-
import org.springframework.core.annotation.OrderProviderComparator;
67-
import org.springframework.core.annotation.OrderUtils;
6868
import org.springframework.lang.UsesJava8;
6969
import org.springframework.util.Assert;
7070
import org.springframework.util.ClassUtils;
@@ -941,7 +941,7 @@ public Object doResolveDependency(DependencyDescriptor descriptor, String beanNa
941941
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
942942
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
943943
if (this.dependencyComparator != null && result instanceof Object[]) {
944-
sortArray((Object[]) result, matchingBeans);
944+
Arrays.sort((Object[]) result, adaptDependencyComparator(matchingBeans));
945945
}
946946
return result;
947947
}
@@ -968,7 +968,7 @@ else if (Collection.class.isAssignableFrom(type) && type.isInterface()) {
968968
TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
969969
Object result = converter.convertIfNecessary(matchingBeans.values(), type);
970970
if (this.dependencyComparator != null && result instanceof List) {
971-
sortList((List<?>) result, matchingBeans);
971+
Collections.sort((List<?>) result, adaptDependencyComparator(matchingBeans));
972972
}
973973
return result;
974974
}
@@ -1029,32 +1029,22 @@ else if (Map.class.isAssignableFrom(type) && type.isInterface()) {
10291029
}
10301030
}
10311031

1032-
private void sortArray(Object[] items, Map<String, Object> matchingBeans) {
1033-
if (this.dependencyComparator instanceof OrderProviderComparator) {
1034-
((OrderProviderComparator) this.dependencyComparator)
1035-
.sortArray(items, createFactoryAwareOrderProvider(matchingBeans));
1032+
private Comparator<Object> adaptDependencyComparator(Map<String, Object> matchingBeans) {
1033+
if (this.dependencyComparator instanceof OrderComparator) {
1034+
return ((OrderComparator) this.dependencyComparator).withSourceProvider(
1035+
createFactoryAwareOrderSourceProvider(matchingBeans));
10361036
}
10371037
else {
1038-
Arrays.sort(items, this.dependencyComparator);
1038+
return this.dependencyComparator;
10391039
}
10401040
}
10411041

1042-
private void sortList(List<?> items, Map<String, Object> matchingBeans) {
1043-
if (this.dependencyComparator instanceof OrderProviderComparator) {
1044-
((OrderProviderComparator) this.dependencyComparator)
1045-
.sortList(items, createFactoryAwareOrderProvider(matchingBeans));
1046-
}
1047-
else {
1048-
Collections.sort(items, this.dependencyComparator);
1049-
}
1050-
}
1051-
1052-
private FactoryAwareOrderProvider createFactoryAwareOrderProvider(Map<String, Object> beans) {
1042+
private FactoryAwareOrderSourceProvider createFactoryAwareOrderSourceProvider(Map<String, Object> beans) {
10531043
IdentityHashMap<Object, String> instancesToBeanNames = new IdentityHashMap<Object, String>();
10541044
for (Map.Entry<String, Object> entry : beans.entrySet()) {
10551045
instancesToBeanNames.put(entry.getValue(), entry.getKey());
10561046
}
1057-
return new FactoryAwareOrderProvider(instancesToBeanNames, this);
1047+
return new FactoryAwareOrderSourceProvider(instancesToBeanNames);
10581048
}
10591049

10601050
/**
@@ -1223,13 +1213,18 @@ protected boolean isPrimary(String beanName, Object beanInstance) {
12231213
/**
12241214
* Return the priority assigned for the given bean instance by
12251215
* the {@code javax.annotation.Priority} annotation.
1226-
* <p>If the annotation is not present, returns {@code null}.
1227-
* @param beanInstance the bean instance to check (can be null)
1216+
* <p>The default implementation delegates to the specified
1217+
* {@link #setDependencyComparator dependency comparator}, checking its
1218+
* {@link OrderComparator#getPriority method} if it is an extension of
1219+
* Spring's common {@link OrderComparator} - typically, an
1220+
* {@link org.springframework.core.annotation.AnnotationAwareOrderComparator}.
1221+
* If no such comparator is present, this implementation returns {@code null}.
1222+
* @param beanInstance the bean instance to check (can be {@code null})
12281223
* @return the priority assigned to that bean or {@code null} if none is set
12291224
*/
12301225
protected Integer getPriority(Object beanInstance) {
1231-
if (beanInstance != null) {
1232-
return OrderUtils.getPriorityValue(beanInstance.getClass());
1226+
if (this.dependencyComparator instanceof OrderComparator) {
1227+
return ((OrderComparator) this.dependencyComparator).getPriority(beanInstance);
12331228
}
12341229
return null;
12351230
}
@@ -1406,4 +1401,36 @@ public Object createDependencyProvider(DependencyDescriptor descriptor, String b
14061401
}
14071402
}
14081403

1404+
1405+
/**
1406+
* An {@link org.springframework.core.OrderComparator.OrderSourceProvider} implementation
1407+
* that is aware of the bean metadata of the instances to sort.
1408+
* <p>Lookup for the method factory of an instance to sort, if any, and let the
1409+
* comparator retrieve the {@link org.springframework.core.annotation.Order}
1410+
* value defined on it. This essentially allows for the following construct:
1411+
*/
1412+
private class FactoryAwareOrderSourceProvider implements OrderComparator.OrderSourceProvider {
1413+
1414+
private final Map<Object, String> instancesToBeanNames;
1415+
1416+
public FactoryAwareOrderSourceProvider(Map<Object, String> instancesToBeanNames) {
1417+
this.instancesToBeanNames = instancesToBeanNames;
1418+
}
1419+
1420+
@Override
1421+
public Object getOrderSource(Object obj) {
1422+
return getFactoryMethod(this.instancesToBeanNames.get(obj));
1423+
}
1424+
1425+
private Method getFactoryMethod(String beanName) {
1426+
if (beanName != null && containsBeanDefinition(beanName)) {
1427+
BeanDefinition bd = getMergedBeanDefinition(beanName);
1428+
if (bd instanceof RootBeanDefinition) {
1429+
return ((RootBeanDefinition) bd).getResolvedFactoryMethod();
1430+
}
1431+
}
1432+
return null;
1433+
}
1434+
}
1435+
14091436
}

spring-beans/src/main/java/org/springframework/beans/factory/support/FactoryAwareOrderProvider.java

Lines changed: 0 additions & 87 deletions
This file was deleted.

spring-beans/src/test/java/org/springframework/beans/factory/DefaultListableBeanFactoryTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@
6969
import org.springframework.beans.factory.xml.ConstructorDependenciesBean;
7070
import org.springframework.beans.propertyeditors.CustomNumberEditor;
7171
import org.springframework.core.MethodParameter;
72+
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
7273
import org.springframework.core.convert.converter.Converter;
7374
import org.springframework.core.convert.support.DefaultConversionService;
7475
import org.springframework.core.convert.support.GenericConversionService;
@@ -1392,6 +1393,7 @@ public void testGetBeanByTypeWithMultiplePrimary() throws Exception {
13921393
@Test
13931394
public void testGetBeanByTypeWithPriority() throws Exception {
13941395
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1396+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
13951397
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
13961398
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
13971399
lbf.registerBeanDefinition("bd1", bd1);
@@ -1403,6 +1405,7 @@ public void testGetBeanByTypeWithPriority() throws Exception {
14031405
@Test
14041406
public void testGetBeanByTypeWithMultiplePriority() throws Exception {
14051407
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1408+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14061409
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
14071410
RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
14081411
lbf.registerBeanDefinition("bd1", bd1);
@@ -1416,6 +1419,7 @@ public void testGetBeanByTypeWithMultiplePriority() throws Exception {
14161419
@Test
14171420
public void testGetBeanByTypeWithPriorityAndNullInstance() throws Exception {
14181421
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1422+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14191423
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
14201424
RootBeanDefinition bd2 = new RootBeanDefinition(NullTestBeanFactoryBean.class);
14211425
lbf.registerBeanDefinition("bd1", bd1);
@@ -1427,6 +1431,7 @@ public void testGetBeanByTypeWithPriorityAndNullInstance() throws Exception {
14271431
@Test
14281432
public void testGetBeanByTypePrimaryHasPrecedenceOverPriority() throws Exception {
14291433
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1434+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
14301435
RootBeanDefinition bd1 = new RootBeanDefinition(HighPriorityTestBean.class);
14311436
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
14321437
bd2.setPrimary(true);
@@ -1697,6 +1702,7 @@ public void testAutowireBeanByTypeWithTwoPrimaryCandidates() {
16971702
@Test
16981703
public void testAutowireBeanByTypeWithTwoMatchesAndPriority() {
16991704
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1705+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
17001706
RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
17011707
RootBeanDefinition bd2 = new RootBeanDefinition(LowPriorityTestBean.class);
17021708
lbf.registerBeanDefinition("test", bd);
@@ -1710,6 +1716,7 @@ public void testAutowireBeanByTypeWithTwoMatchesAndPriority() {
17101716
@Test
17111717
public void testAutowireBeanByTypeWithIdenticalPriorityCandidates() {
17121718
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1719+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
17131720
RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
17141721
RootBeanDefinition bd2 = new RootBeanDefinition(HighPriorityTestBean.class);
17151722
lbf.registerBeanDefinition("test", bd);
@@ -1730,6 +1737,7 @@ public void testAutowireBeanByTypeWithIdenticalPriorityCandidates() {
17301737
@Test
17311738
public void testAutowireBeanByTypePrimaryTakesPrecedenceOverPriority() {
17321739
DefaultListableBeanFactory lbf = new DefaultListableBeanFactory();
1740+
lbf.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
17331741
RootBeanDefinition bd = new RootBeanDefinition(HighPriorityTestBean.class);
17341742
RootBeanDefinition bd2 = new RootBeanDefinition(TestBean.class);
17351743
bd2.setPrimary(true);

0 commit comments

Comments
 (0)