提交 978adbda 编写于 作者: S Sam Brannen

Avoid duplicate lookups of @ControllerAdvice annotations

See gh-23163
上级 ed6fbddd
...@@ -85,12 +85,28 @@ public class ControllerAdviceBean implements Ordered { ...@@ -85,12 +85,28 @@ public class ControllerAdviceBean implements Ordered {
} }
/** /**
* Create a {@code ControllerAdviceBean} using the given bean name. * Create a {@code ControllerAdviceBean} using the given bean name and
* {@code BeanFactory}.
* @param beanName the name of the bean * @param beanName the name of the bean
* @param beanFactory a {@code BeanFactory} to retrieve the bean type initially * @param beanFactory a {@code BeanFactory} to retrieve the bean type initially
* and later to resolve the actual bean * and later to resolve the actual bean
*/ */
public ControllerAdviceBean(String beanName, BeanFactory beanFactory) { public ControllerAdviceBean(String beanName, BeanFactory beanFactory) {
this(beanName, beanFactory, null);
}
/**
* Create a {@code ControllerAdviceBean} using the given bean name,
* {@code BeanFactory}, and {@link ControllerAdvice @ControllerAdvice}
* annotation.
* @param beanName the name of the bean
* @param beanFactory a {@code BeanFactory} to retrieve the bean type initially
* and later to resolve the actual bean
* @param controllerAdvice the {@code @ControllerAdvice} annotation for the
* bean, or {@code null} if not yet retrieved
* @since 5.2
*/
public ControllerAdviceBean(String beanName, BeanFactory beanFactory, @Nullable ControllerAdvice controllerAdvice) {
Assert.hasText(beanName, "Bean name must contain text"); Assert.hasText(beanName, "Bean name must contain text");
Assert.notNull(beanFactory, "BeanFactory must not be null"); Assert.notNull(beanFactory, "BeanFactory must not be null");
Assert.isTrue(beanFactory.containsBean(beanName), () -> "BeanFactory [" + beanFactory Assert.isTrue(beanFactory.containsBean(beanName), () -> "BeanFactory [" + beanFactory
...@@ -98,7 +114,8 @@ public class ControllerAdviceBean implements Ordered { ...@@ -98,7 +114,8 @@ public class ControllerAdviceBean implements Ordered {
this.beanOrName = beanName; this.beanOrName = beanName;
this.beanType = getBeanType(beanName, beanFactory); this.beanType = getBeanType(beanName, beanFactory);
this.beanTypePredicate = createBeanTypePredicate(this.beanType); this.beanTypePredicate = (controllerAdvice != null ? createBeanTypePredicate(controllerAdvice)
: createBeanTypePredicate(this.beanType));
this.beanFactory = beanFactory; this.beanFactory = beanFactory;
this.order = initOrderFromBeanType(this.beanType); this.order = initOrderFromBeanType(this.beanType);
} }
...@@ -186,8 +203,11 @@ public class ControllerAdviceBean implements Ordered { ...@@ -186,8 +203,11 @@ public class ControllerAdviceBean implements Ordered {
public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) { public static List<ControllerAdviceBean> findAnnotatedBeans(ApplicationContext context) {
List<ControllerAdviceBean> adviceBeans = new ArrayList<>(); List<ControllerAdviceBean> adviceBeans = new ArrayList<>();
for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, Object.class)) { for (String name : BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, Object.class)) {
if (context.findAnnotationOnBean(name, ControllerAdvice.class) != null) { ControllerAdvice controllerAdvice = context.findAnnotationOnBean(name, ControllerAdvice.class);
adviceBeans.add(new ControllerAdviceBean(name, context)); if (controllerAdvice != null) {
// Use the @ControllerAdvice annotation found by findAnnotationOnBean()
// in order to avoid a subsequent lookup of the same annotation.
adviceBeans.add(new ControllerAdviceBean(name, context, controllerAdvice));
} }
} }
return adviceBeans; return adviceBeans;
...@@ -199,15 +219,18 @@ public class ControllerAdviceBean implements Ordered { ...@@ -199,15 +219,18 @@ public class ControllerAdviceBean implements Ordered {
} }
private static HandlerTypePredicate createBeanTypePredicate(Class<?> beanType) { private static HandlerTypePredicate createBeanTypePredicate(Class<?> beanType) {
ControllerAdvice annotation = (beanType != null ? ControllerAdvice controllerAdvice = (beanType != null ?
AnnotatedElementUtils.findMergedAnnotation(beanType, ControllerAdvice.class) : null); AnnotatedElementUtils.findMergedAnnotation(beanType, ControllerAdvice.class) : null);
return createBeanTypePredicate(controllerAdvice);
}
if (annotation != null) { private static HandlerTypePredicate createBeanTypePredicate(ControllerAdvice controllerAdvice) {
if (controllerAdvice != null) {
return HandlerTypePredicate.builder() return HandlerTypePredicate.builder()
.basePackage(annotation.basePackages()) .basePackage(controllerAdvice.basePackages())
.basePackageClass(annotation.basePackageClasses()) .basePackageClass(controllerAdvice.basePackageClasses())
.assignableType(annotation.assignableTypes()) .assignableType(controllerAdvice.assignableTypes())
.annotation(annotation.annotations()) .annotation(controllerAdvice.annotations())
.build(); .build();
} }
return HandlerTypePredicate.forAnyHandlerType(); return HandlerTypePredicate.forAnyHandlerType();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册