Skip to content

improve performance of getHandlerInternal #29589

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

ShijunDeng
Copy link

@ShijunDeng ShijunDeng commented Nov 27, 2022

In some scenarios, we need to get HandlerMethod ahead of org.springframework.web.reactive.DispatcherHandler, such as an implement of authentication by WebFilter

public class AuthFilter implements WebFilter, Ordered {

    @Autowired
    private RequestMappingHandlerMapping handlerMapping;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
        return handlerMapping.getHandler(exchange).switchIfEmpty(chain.filter(exchange))
            .flatMap(handler -> {
                    if (handler instanceof HandlerMethod) {
                        HandlerMethod methodHandle = (HandlerMethod) handler;
                        CheckPermission permission = methodHandle.getMethodAnnotation(CheckPermission.class);
                        if (Objects.isNull(permission)) {
                            permission = AnnotationUtils.findAnnotation(methodHandle.getBeanType(), CheckPermission.class);
                        }

                        if (Objects.nonNull(permission)) {
                            // TODO  do something..
                        }
                    }
                    return chain.filter(exchange);
                }
            );
    }
}

HandlerMethod is necessary but there is no alternative way to get it withon WebFilter, which limited the capabilities of WebFilter. so, we need call getHandler, however this may lead to repeated call of lookupHandlerMethod as issue:

public Mono<HandlerMethod> getHandlerInternal(ServerWebExchange exchange) {

To avoid duplicate search for HandlerMethod in mapping.getHandler , I suggest implementing a improved getHandlerInternal, in which HandlerMethod would be searched in attributes at first.

Object handlerMethod = exchange.getAttributes().get(BEST_MATCHING_HANDLER_ATTRIBUTE);
if (handlerMethod instanceof HandlerMethod) {
	return Mono.just((HandlerMethod) handlerMethod);
}

related issue:#29591

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Nov 27, 2022
@rstoyanchev
Copy link
Contributor

WebFilters are called first and are not meant to know what the DispatcherHandler will do or what controller method it will choose. You can of course call a HandlerMapping from a WebFilter, but that is not something that we recommend or support.

@rstoyanchev rstoyanchev closed this Dec 2, 2022
@rstoyanchev rstoyanchev added status: declined A suggestion or change that we don't feel we should currently apply and removed status: waiting-for-triage An issue we've not yet triaged or decided on labels Dec 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: declined A suggestion or change that we don't feel we should currently apply
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants