Avoid unnecessary annotation introspection on framework methods
Issue: SPR-16933
This commit is contained in:
@@ -188,8 +188,8 @@ class ConfigurationClassEnhancer {
|
|||||||
@Override
|
@Override
|
||||||
public int accept(Method method) {
|
public int accept(Method method) {
|
||||||
for (int i = 0; i < this.callbacks.length; i++) {
|
for (int i = 0; i < this.callbacks.length; i++) {
|
||||||
if (!(this.callbacks[i] instanceof ConditionalCallback) ||
|
Callback callback = this.callbacks[i];
|
||||||
((ConditionalCallback) this.callbacks[i]).isMatch(method)) {
|
if (!(callback instanceof ConditionalCallback) || ((ConditionalCallback) callback).isMatch(method)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -285,6 +285,10 @@ class ConfigurationClassEnhancer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isMatch(Method candidateMethod) {
|
public boolean isMatch(Method candidateMethod) {
|
||||||
|
return isSetBeanFactory(candidateMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isSetBeanFactory(Method candidateMethod) {
|
||||||
return (candidateMethod.getName().equals("setBeanFactory") &&
|
return (candidateMethod.getName().equals("setBeanFactory") &&
|
||||||
candidateMethod.getParameterCount() == 1 &&
|
candidateMethod.getParameterCount() == 1 &&
|
||||||
BeanFactory.class == candidateMethod.getParameterTypes()[0] &&
|
BeanFactory.class == candidateMethod.getParameterTypes()[0] &&
|
||||||
@@ -430,6 +434,7 @@ class ConfigurationClassEnhancer {
|
|||||||
@Override
|
@Override
|
||||||
public boolean isMatch(Method candidateMethod) {
|
public boolean isMatch(Method candidateMethod) {
|
||||||
return (candidateMethod.getDeclaringClass() != Object.class &&
|
return (candidateMethod.getDeclaringClass() != Object.class &&
|
||||||
|
!BeanFactoryAwareMethodInterceptor.isSetBeanFactory(candidateMethod) &&
|
||||||
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
|
BeanAnnotationHelper.isBeanAnnotated(candidateMethod));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2017 the original author or authors.
|
* Copyright 2002-2018 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -41,6 +41,7 @@ import org.springframework.core.MethodIntrospector;
|
|||||||
import org.springframework.core.annotation.AnnotatedElementUtils;
|
import org.springframework.core.annotation.AnnotatedElementUtils;
|
||||||
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
|
||||||
import org.springframework.lang.Nullable;
|
import org.springframework.lang.Nullable;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
|
|
||||||
@@ -137,7 +138,7 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
|
|||||||
protected void processBean(
|
protected void processBean(
|
||||||
final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
|
final List<EventListenerFactory> factories, final String beanName, final Class<?> targetType) {
|
||||||
|
|
||||||
if (!this.nonAnnotatedClasses.contains(targetType)) {
|
if (!this.nonAnnotatedClasses.contains(targetType) && !isSpringContainerClass(targetType)) {
|
||||||
Map<Method, EventListener> annotatedMethods = null;
|
Map<Method, EventListener> annotatedMethods = null;
|
||||||
try {
|
try {
|
||||||
annotatedMethods = MethodIntrospector.selectMethods(targetType,
|
annotatedMethods = MethodIntrospector.selectMethods(targetType,
|
||||||
@@ -181,4 +182,16 @@ public class EventListenerMethodProcessor implements SmartInitializingSingleton,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine whether the given class is an {@code org.springframework}
|
||||||
|
* bean class that is not annotated as a user or test {@link Component}...
|
||||||
|
* which indicates that there is no {@link EventListener} to be found there.
|
||||||
|
* @since 5.1
|
||||||
|
*/
|
||||||
|
private static boolean isSpringContainerClass(Class<?> clazz) {
|
||||||
|
return (clazz.getName().startsWith("org.springframework.") &&
|
||||||
|
!AnnotatedElementUtils.isAnnotated(clazz, Component.class));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,8 +228,8 @@ public abstract class AnnotatedElementUtils {
|
|||||||
return hasMetaAnnotationTypes(element, null, annotationName);
|
return hasMetaAnnotationTypes(element, null, annotationName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasMetaAnnotationTypes(AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType,
|
private static boolean hasMetaAnnotationTypes(
|
||||||
@Nullable String annotationName) {
|
AnnotatedElement element, @Nullable Class<? extends Annotation> annotationType, @Nullable String annotationName) {
|
||||||
|
|
||||||
return Boolean.TRUE.equals(
|
return Boolean.TRUE.equals(
|
||||||
searchWithGetSemantics(element, annotationType, annotationName, new SimpleAnnotationProcessor<Boolean>() {
|
searchWithGetSemantics(element, annotationType, annotationName, new SimpleAnnotationProcessor<Boolean>() {
|
||||||
@@ -680,6 +680,11 @@ public abstract class AnnotatedElementUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Shortcut: no non-java annotations to be found on plain Java classes and org.springframework.lang types...
|
||||||
|
if (AnnotationUtils.hasPlainJavaAnnotationsOnly(element) && !annotationType.getName().startsWith("java")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Exhaustive retrieval of merged annotation attributes...
|
// Exhaustive retrieval of merged annotation attributes...
|
||||||
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
|
AnnotationAttributes attributes = findMergedAnnotationAttributes(element, annotationType, false, false);
|
||||||
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
|
return (attributes != null ? AnnotationUtils.synthesizeAnnotation(attributes, annotationType, element) : null);
|
||||||
@@ -1007,7 +1012,7 @@ public abstract class AnnotatedElementUtils {
|
|||||||
|
|
||||||
if (containerType != null && !processor.aggregates()) {
|
if (containerType != null && !processor.aggregates()) {
|
||||||
throw new IllegalArgumentException(
|
throw new IllegalArgumentException(
|
||||||
"Searches for repeatable annotations must supply an aggregating Processor");
|
"Searches for repeatable annotations must supply an aggregating Processor");
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -641,11 +641,13 @@ public abstract class AnnotationUtils {
|
|||||||
if (anns.length == 0) {
|
if (anns.length == 0) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (anns.length == 1) {
|
for (Annotation ann : anns) {
|
||||||
Class<?> annType = anns[0].annotationType();
|
String name = ann.annotationType().getName();
|
||||||
return (annType != Nullable.class && annType != Deprecated.class);
|
if (!name.startsWith("java.lang.") && !name.startsWith("org.springframework.lang.")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isOverride(Method method, Method candidate) {
|
private static boolean isOverride(Method method, Method candidate) {
|
||||||
@@ -920,11 +922,11 @@ public abstract class AnnotationUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine if the {@link Annotation} with the supplied name is defined in the
|
* Determine if the given annotated element is defined in a
|
||||||
* {@code java.lang.annotation} or {@code org.springframework.lang} package.
|
* {@code java} or in the {@code org.springframework.lang} package.
|
||||||
* @param annotatedElement the potential annotation type to check
|
* @param annotatedElement the annotated element to check
|
||||||
* @return {@code true} if the annotation is in the {@code java.lang.annotation}
|
* @return {@code true} if the given element is in a {@code java}
|
||||||
* or {@code org.springframework.lang} package
|
* package or in the {@code org.springframework.lang} package
|
||||||
* @since 5.1
|
* @since 5.1
|
||||||
*/
|
*/
|
||||||
static boolean hasPlainJavaAnnotationsOnly(@Nullable Object annotatedElement) {
|
static boolean hasPlainJavaAnnotationsOnly(@Nullable Object annotatedElement) {
|
||||||
|
|||||||
Reference in New Issue
Block a user