Details
Description
Hello,
We ran load tests and found that findAnnotation was one of the top method using CPU despite it uses caching.
We could correct this situation by caching NULL values with this simple change:
--- C:\Project\AnnotationUtils.java 2018-04-16 16:16:04.974657900 -0400 +++ C:\Project\src\main\java\org\springframework\core\annotation\AnnotationUtils.java 2018-03-12 16:58:54.540000000 -0400 @@ -136,6 +148,14 @@ new ConcurrentReferenceHashMap<Method, AliasDescriptor>(256); private static transient Log logger; + + private static final Annotation NULL_ANNOTATION = new Annotation() { + + @Override + public Class<? extends Annotation> annotationType() { + // TODO Auto-generated method stub + return null; + }}; /** @@ -558,13 +578,14 @@ @SuppressWarnings("unchecked") public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) { Assert.notNull(method, "Method must not be null"); + if (annotationType == null) { return null; } AnnotationCacheKey cacheKey = new AnnotationCacheKey(method, annotationType); A result = (A) findAnnotationCache.get(cacheKey); - + if (result == null) { Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method); result = findAnnotation((AnnotatedElement) resolvedMethod, annotationType); @@ -595,9 +616,13 @@ if (result != null) { result = synthesizeAnnotation(result, method); findAnnotationCache.put(cacheKey, result); + }else { + findAnnotationCache.put(cacheKey, NULL_ANNOTATION); } } - + if(NULL_ANNOTATION == result) { + result = null; + } return result; } @@ -691,8 +716,13 @@ if (result != null && synthesize) { result = synthesizeAnnotation(result, clazz); findAnnotationCache.put(cacheKey, result); + }else if(result == null && synthesize) { + findAnnotationCache.put(cacheKey, NULL_ANNOTATION); } } + if(NULL_ANNOTATION == result) { + result = null; + } return result; }
Often findAnnotation returns null - adding a key with NULL_ANNOTATION as the value resolved the issue. NULL_ANNOTATION is reverted to null prior returning.
After this change we observed an appreciable 4-5% performance improvement in our app across the board.
Attachments
Issue Links
- is related to
-
SPR-16060 Annotations on generic interface methods not found by AnnotationUtils
-
- Closed
-
-
SPR-17064 Cache order result per Class in OrderUtils (for AnnotationAwareOrderComparator)
-
- Closed
-
-
SPR-16933 Avoid unnecessary synthesizable annotation processing
-
- Closed
-
- relates to
-
SPR-11882 ReflectionUtils slow down application startup on WebSphere
-
- Closed
-
-
SPR-13621 Performance regression on startup (in particular in AnnotationUtils)
-
- Closed
-
-
SPR-16675 Comprehensively cache annotated methods for interfaces and superclasses
-
- Closed
-