diff --git a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java index 92892a4863a..a7a257da3f4 100644 --- a/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java +++ b/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure/web/servlet/CompositeHandlerExceptionResolver.java @@ -18,7 +18,6 @@ package org.springframework.boot.actuate.autoconfigure.web.servlet; import java.util.ArrayList; import java.util.List; -import java.util.Objects; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -47,36 +46,45 @@ class CompositeHandlerExceptionResolver implements HandlerExceptionResolver { @Autowired private ListableBeanFactory beanFactory; - private List resolvers; + private transient List resolvers; @Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { - if (this.resolvers == null) { - this.resolvers = extractResolvers(); + for (HandlerExceptionResolver resolver : getResolvers()) { + ModelAndView resolved = resolver.resolveException(request, response, handler, ex); + if (resolved != null) { + return resolved; + } } - return this.resolvers.stream().map((resolver) -> resolver.resolveException(request, response, handler, ex)) - .filter(Objects::nonNull).findFirst().orElse(null); + return null; } - private List extractResolvers() { - List list = new ArrayList<>(); - BeanFactory beanFactory = this.beanFactory; - while (beanFactory != null) { - if (beanFactory instanceof ListableBeanFactory) { - list.addAll( - ((ListableBeanFactory) beanFactory).getBeansOfType(HandlerExceptionResolver.class).values()); + private List getResolvers() { + List resolvers = this.resolvers; + if (resolvers == null) { + resolvers = new ArrayList<>(); + collectResolverBeans(resolvers, this.beanFactory); + resolvers.remove(this); + AnnotationAwareOrderComparator.sort(resolvers); + if (resolvers.isEmpty()) { + resolvers.add(new DefaultErrorAttributes()); + resolvers.add(new DefaultHandlerExceptionResolver()); } - beanFactory = (beanFactory instanceof HierarchicalBeanFactory) - ? ((HierarchicalBeanFactory) beanFactory).getParentBeanFactory() : null; + this.resolvers = resolvers; + } + return resolvers; + } + + private void collectResolverBeans(List resolvers, BeanFactory beanFactory) { + if (beanFactory instanceof ListableBeanFactory) { + ListableBeanFactory listableBeanFactory = (ListableBeanFactory) beanFactory; + resolvers.addAll(listableBeanFactory.getBeansOfType(HandlerExceptionResolver.class).values()); } - list.remove(this); - AnnotationAwareOrderComparator.sort(list); - if (list.isEmpty()) { - list.add(new DefaultErrorAttributes()); - list.add(new DefaultHandlerExceptionResolver()); + if (beanFactory instanceof HierarchicalBeanFactory) { + HierarchicalBeanFactory hierarchicalBeanFactory = (HierarchicalBeanFactory) beanFactory; + collectResolverBeans(resolvers, hierarchicalBeanFactory.getParentBeanFactory()); } - return list; } }