Search in sources :

Example 1 with ControllerAdviceBean

use of org.springframework.web.method.ControllerAdviceBean in project spring-framework by spring-projects.

the class RequestMappingHandlerAdapter method initControllerAdviceCache.

private void initControllerAdviceCache() {
    if (getApplicationContext() == null) {
        return;
    }
    if (logger.isInfoEnabled()) {
        logger.info("Looking for @ControllerAdvice: " + getApplicationContext());
    }
    List<ControllerAdviceBean> beans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    AnnotationAwareOrderComparator.sort(beans);
    for (ControllerAdviceBean bean : beans) {
        Class<?> beanType = bean.getBeanType();
        Set<Method> attrMethods = selectMethods(beanType, ATTRIBUTE_METHODS);
        if (!attrMethods.isEmpty()) {
            this.attributeAdviceCache.put(bean, attrMethods);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @ModelAttribute methods in " + bean);
            }
        }
        Set<Method> binderMethods = selectMethods(beanType, BINDER_METHODS);
        if (!binderMethods.isEmpty()) {
            this.binderAdviceCache.put(bean, binderMethods);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @InitBinder methods in " + bean);
            }
        }
        ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
        if (resolver.hasExceptionMappings()) {
            this.exceptionHandlerAdviceCache.put(bean, resolver);
            if (logger.isInfoEnabled()) {
                logger.info("Detected @ExceptionHandler methods in " + bean);
            }
        }
    }
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) InvocableHandlerMethod(org.springframework.web.reactive.result.method.InvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) SyncInvocableHandlerMethod(org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean)

Example 2 with ControllerAdviceBean

use of org.springframework.web.method.ControllerAdviceBean in project spring-framework by spring-projects.

the class RequestScopedControllerAdviceIntegrationTests method loadContextWithRequestScopedControllerAdvice.

// gh-23985
@Test
void loadContextWithRequestScopedControllerAdvice() {
    AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
    context.setServletContext(new MockServletContext());
    context.register(Config.class);
    assertThatCode(context::refresh).doesNotThrowAnyException();
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(context);
    assertThat(adviceBeans).hasSize(1);
    // 
    assertThat(adviceBeans.get(0)).returns(RequestScopedControllerAdvice.class, // 
    ControllerAdviceBean::getBeanType).returns(42, ControllerAdviceBean::getOrder);
    context.close();
}
Also used : AnnotationConfigWebApplicationContext(org.springframework.web.context.support.AnnotationConfigWebApplicationContext) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean) MockServletContext(org.springframework.web.testfixture.servlet.MockServletContext) Test(org.junit.jupiter.api.Test)

Example 3 with ControllerAdviceBean

use of org.springframework.web.method.ControllerAdviceBean in project spring-framework by spring-projects.

the class ExceptionHandlerExceptionResolver method initExceptionHandlerAdviceCache.

private void initExceptionHandlerAdviceCache() {
    if (getApplicationContext() == null) {
        return;
    }
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    for (ControllerAdviceBean adviceBean : adviceBeans) {
        Class<?> beanType = adviceBean.getBeanType();
        if (beanType == null) {
            throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
        }
        ExceptionHandlerMethodResolver resolver = new ExceptionHandlerMethodResolver(beanType);
        if (resolver.hasExceptionMappings()) {
            this.exceptionHandlerAdviceCache.put(adviceBean, resolver);
        }
        if (ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
            this.responseBodyAdvice.add(adviceBean);
        }
    }
    if (logger.isDebugEnabled()) {
        int handlerSize = this.exceptionHandlerAdviceCache.size();
        int adviceSize = this.responseBodyAdvice.size();
        if (handlerSize == 0 && adviceSize == 0) {
            logger.debug("ControllerAdvice beans: none");
        } else {
            logger.debug("ControllerAdvice beans: " + handlerSize + " @ExceptionHandler, " + adviceSize + " ResponseBodyAdvice");
        }
    }
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean)

Example 4 with ControllerAdviceBean

use of org.springframework.web.method.ControllerAdviceBean in project spring-framework by spring-projects.

the class ExceptionHandlerExceptionResolver method getExceptionHandlerMethod.

/**
 * Find an {@code @ExceptionHandler} method for the given exception. The default
 * implementation searches methods in the class hierarchy of the controller first
 * and if not found, it continues searching for additional {@code @ExceptionHandler}
 * methods assuming some {@linkplain ControllerAdvice @ControllerAdvice}
 * Spring-managed beans were detected.
 * @param handlerMethod the method where the exception was raised (may be {@code null})
 * @param exception the raised exception
 * @return a method to handle the exception, or {@code null} if none
 */
@Nullable
protected ServletInvocableHandlerMethod getExceptionHandlerMethod(@Nullable HandlerMethod handlerMethod, Exception exception) {
    Class<?> handlerType = null;
    if (handlerMethod != null) {
        // Local exception handler methods on the controller class itself.
        // To be invoked through the proxy, even in case of an interface-based proxy.
        handlerType = handlerMethod.getBeanType();
        ExceptionHandlerMethodResolver resolver = this.exceptionHandlerCache.computeIfAbsent(handlerType, ExceptionHandlerMethodResolver::new);
        Method method = resolver.resolveMethod(exception);
        if (method != null) {
            return new ServletInvocableHandlerMethod(handlerMethod.getBean(), method, this.applicationContext);
        }
        // and annotation presence), use target class instead of interface-based proxy.
        if (Proxy.isProxyClass(handlerType)) {
            handlerType = AopUtils.getTargetClass(handlerMethod.getBean());
        }
    }
    for (Map.Entry<ControllerAdviceBean, ExceptionHandlerMethodResolver> entry : this.exceptionHandlerAdviceCache.entrySet()) {
        ControllerAdviceBean advice = entry.getKey();
        if (advice.isApplicableToBeanType(handlerType)) {
            ExceptionHandlerMethodResolver resolver = entry.getValue();
            Method method = resolver.resolveMethod(exception);
            if (method != null) {
                return new ServletInvocableHandlerMethod(advice.resolveBean(), method, this.applicationContext);
            }
        }
    }
    return null;
}
Also used : ExceptionHandlerMethodResolver(org.springframework.web.method.annotation.ExceptionHandlerMethodResolver) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) ModelMap(org.springframework.ui.ModelMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean) Nullable(org.springframework.lang.Nullable)

Example 5 with ControllerAdviceBean

use of org.springframework.web.method.ControllerAdviceBean in project spring-framework by spring-projects.

the class RequestMappingHandlerAdapter method initControllerAdviceCache.

private void initControllerAdviceCache() {
    if (getApplicationContext() == null) {
        return;
    }
    List<ControllerAdviceBean> adviceBeans = ControllerAdviceBean.findAnnotatedBeans(getApplicationContext());
    List<Object> requestResponseBodyAdviceBeans = new ArrayList<>();
    for (ControllerAdviceBean adviceBean : adviceBeans) {
        Class<?> beanType = adviceBean.getBeanType();
        if (beanType == null) {
            throw new IllegalStateException("Unresolvable type for ControllerAdviceBean: " + adviceBean);
        }
        Set<Method> attrMethods = MethodIntrospector.selectMethods(beanType, MODEL_ATTRIBUTE_METHODS);
        if (!attrMethods.isEmpty()) {
            this.modelAttributeAdviceCache.put(adviceBean, attrMethods);
        }
        Set<Method> binderMethods = MethodIntrospector.selectMethods(beanType, INIT_BINDER_METHODS);
        if (!binderMethods.isEmpty()) {
            this.initBinderAdviceCache.put(adviceBean, binderMethods);
        }
        if (RequestBodyAdvice.class.isAssignableFrom(beanType) || ResponseBodyAdvice.class.isAssignableFrom(beanType)) {
            requestResponseBodyAdviceBeans.add(adviceBean);
        }
    }
    if (!requestResponseBodyAdviceBeans.isEmpty()) {
        this.requestResponseBodyAdvice.addAll(0, requestResponseBodyAdviceBeans);
    }
    if (logger.isDebugEnabled()) {
        int modelSize = this.modelAttributeAdviceCache.size();
        int binderSize = this.initBinderAdviceCache.size();
        int reqCount = getBodyAdviceCount(RequestBodyAdvice.class);
        int resCount = getBodyAdviceCount(ResponseBodyAdvice.class);
        if (modelSize == 0 && binderSize == 0 && reqCount == 0 && resCount == 0) {
            logger.debug("ControllerAdvice beans: none");
        } else {
            logger.debug("ControllerAdvice beans: " + modelSize + " @ModelAttribute, " + binderSize + " @InitBinder, " + reqCount + " RequestBodyAdvice, " + resCount + " ResponseBodyAdvice");
        }
    }
}
Also used : ArrayList(java.util.ArrayList) InvocableHandlerMethod(org.springframework.web.method.support.InvocableHandlerMethod) HandlerMethod(org.springframework.web.method.HandlerMethod) Method(java.lang.reflect.Method) ControllerAdviceBean(org.springframework.web.method.ControllerAdviceBean)

Aggregations

ControllerAdviceBean (org.springframework.web.method.ControllerAdviceBean)9 Method (java.lang.reflect.Method)5 HandlerMethod (org.springframework.web.method.HandlerMethod)5 ExceptionHandlerMethodResolver (org.springframework.web.method.annotation.ExceptionHandlerMethodResolver)5 InvocableHandlerMethod (org.springframework.web.reactive.result.method.InvocableHandlerMethod)3 SyncInvocableHandlerMethod (org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod)3 ArrayList (java.util.ArrayList)2 LinkedHashMap (java.util.LinkedHashMap)2 Map (java.util.Map)2 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)2 Nullable (org.springframework.lang.Nullable)2 Test (org.junit.jupiter.api.Test)1 ApplicationContext (org.springframework.context.ApplicationContext)1 ModelMap (org.springframework.ui.ModelMap)1 AnnotationConfigWebApplicationContext (org.springframework.web.context.support.AnnotationConfigWebApplicationContext)1 InvocableHandlerMethod (org.springframework.web.method.support.InvocableHandlerMethod)1 MockServletContext (org.springframework.web.testfixture.servlet.MockServletContext)1