Skip to content

Commit d0bbbf4

Browse files
committed
OrderUtils caches order values (for AnnotationAwareOrderComparator)
Issue: SPR-17064
1 parent 1f5d0fa commit d0bbbf4

File tree

2 files changed

+46
-14
lines changed

2 files changed

+46
-14
lines changed

spring-core/src/main/java/org/springframework/core/annotation/OrderUtils.java

Lines changed: 37 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,9 +17,11 @@
1717
package org.springframework.core.annotation;
1818

1919
import java.lang.annotation.Annotation;
20+
import java.util.Map;
2021

2122
import org.springframework.lang.Nullable;
2223
import org.springframework.util.ClassUtils;
24+
import org.springframework.util.ConcurrentReferenceHashMap;
2325

2426
/**
2527
* General utility for determining the order of an object based on its type declaration.
@@ -34,6 +36,10 @@
3436
@SuppressWarnings("unchecked")
3537
public abstract class OrderUtils {
3638

39+
/** Cache marker for a non-annotated Class. */
40+
private static final Object NOT_ANNOTATED = new Object();
41+
42+
3743
@Nullable
3844
private static Class<? extends Annotation> priorityAnnotationType;
3945

@@ -49,6 +55,13 @@ public abstract class OrderUtils {
4955
}
5056

5157

58+
/** Cache for @Order value (or NOT_ANNOTATED marker) per Class. */
59+
private static final Map<Class<?>, Object> orderCache = new ConcurrentReferenceHashMap<>(64);
60+
61+
/** Cache for @Priority value (or NOT_ANNOTATED marker) per Class. */
62+
private static final Map<Class<?>, Object> priorityCache = new ConcurrentReferenceHashMap<>();
63+
64+
5265
/**
5366
* Return the order on the specified {@code type}, or the specified
5467
* default value if none can be found.
@@ -86,15 +99,20 @@ public static Integer getOrder(Class<?> type, @Nullable Integer defaultOrder) {
8699
*/
87100
@Nullable
88101
public static Integer getOrder(Class<?> type) {
102+
Object cached = orderCache.get(type);
103+
if (cached != null) {
104+
return (cached instanceof Integer ? (Integer) cached : null);
105+
}
89106
Order order = AnnotationUtils.findAnnotation(type, Order.class);
107+
Integer result;
90108
if (order != null) {
91-
return order.value();
109+
result = order.value();
92110
}
93-
Integer priorityOrder = getPriority(type);
94-
if (priorityOrder != null) {
95-
return priorityOrder;
111+
else {
112+
result = getPriority(type);
96113
}
97-
return null;
114+
orderCache.put(type, (result != null ? result : NOT_ANNOTATED));
115+
return result;
98116
}
99117

100118
/**
@@ -105,13 +123,20 @@ public static Integer getOrder(Class<?> type) {
105123
*/
106124
@Nullable
107125
public static Integer getPriority(Class<?> type) {
108-
if (priorityAnnotationType != null) {
109-
Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType);
110-
if (priority != null) {
111-
return (Integer) AnnotationUtils.getValue(priority);
112-
}
126+
if (priorityAnnotationType == null) {
127+
return null;
128+
}
129+
Object cached = priorityCache.get(type);
130+
if (cached != null) {
131+
return (cached instanceof Integer ? (Integer) cached : null);
132+
}
133+
Annotation priority = AnnotationUtils.findAnnotation(type, priorityAnnotationType);
134+
Integer result = null;
135+
if (priority != null) {
136+
result = (Integer) AnnotationUtils.getValue(priority);
113137
}
114-
return null;
138+
priorityCache.put(type, (result != null ? result : NOT_ANNOTATED));
139+
return result;
115140
}
116141

117142
}

spring-core/src/test/java/org/springframework/core/annotation/OrderUtilsTests.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -23,41 +23,48 @@
2323
import static org.junit.Assert.*;
2424

2525
/**
26-
*
2726
* @author Stephane Nicoll
27+
* @author Juergen Hoeller
2828
*/
2929
public class OrderUtilsTests {
3030

3131
@Test
3232
public void getSimpleOrder() {
3333
assertEquals(Integer.valueOf(50), OrderUtils.getOrder(SimpleOrder.class, null));
34+
assertEquals(Integer.valueOf(50), OrderUtils.getOrder(SimpleOrder.class, null));
3435
}
3536

3637
@Test
3738
public void getPriorityOrder() {
3839
assertEquals(Integer.valueOf(55), OrderUtils.getOrder(SimplePriority.class, null));
40+
assertEquals(Integer.valueOf(55), OrderUtils.getOrder(SimplePriority.class, null));
3941
}
4042

4143
@Test
4244
public void getOrderWithBoth() {
4345
assertEquals(Integer.valueOf(50), OrderUtils.getOrder(OrderAndPriority.class, null));
46+
assertEquals(Integer.valueOf(50), OrderUtils.getOrder(OrderAndPriority.class, null));
4447
}
4548

4649
@Test
4750
public void getDefaultOrder() {
4851
assertEquals(33, OrderUtils.getOrder(NoOrder.class, 33));
52+
assertEquals(33, OrderUtils.getOrder(NoOrder.class, 33));
4953
}
5054

5155
@Test
5256
public void getPriorityValueNoAnnotation() {
5357
assertNull(OrderUtils.getPriority(SimpleOrder.class));
58+
assertNull(OrderUtils.getPriority(SimpleOrder.class));
5459
}
5560

5661
@Test
5762
public void getPriorityValue() {
5863
assertEquals(Integer.valueOf(55), OrderUtils.getPriority(OrderAndPriority.class));
64+
assertEquals(Integer.valueOf(55), OrderUtils.getPriority(OrderAndPriority.class));
5965
}
6066

67+
6168
@Order(50)
6269
private static class SimpleOrder {}
6370

0 commit comments

Comments
 (0)