Spring MVC : ResourceUrlProviderExposingInterceptor

本文深入解析了SpringMVC中的ResourceUrlProviderExposingInterceptor组件,阐述了它如何通过预处理请求,将ResourceUrlProvider实例注入到请求属性中,以提供资源URL的访问路径。此外,还详细介绍了其在SpringMVC配置类WebMvcConfigurationSupport中的启用过程及在DispatcherServlet请求处理流程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

概述

ResourceUrlProviderExposingInterceptorSpring MVC的一个HandlerInterceptor,用于向请求添加一个属性,属性名称为ResourceUrlProvider.class.getName(),值是Spring MVC配置定义的一个资源URL提供者对象ResourceUrlProvider

缺省情况下,Spring MVC配置机制会主动构建一个ResourceUrlProviderExposingInterceptor应用于所有的请求。

关于应用

1. 引入

缺省被WebMvcConfigurationSupport启用:

// WebMvcConfigurationSupport 代码片段
// 

	/**
	 * Provide access to the shared handler interceptors used to configure
	 * {@link HandlerMapping} instances with.
	 * <p>This method cannot be overridden; use {@link #addInterceptors} instead.
	 */
	protected final Object[] getInterceptors() {
		if (this.interceptors == null) {
			InterceptorRegistry registry = new InterceptorRegistry();
			addInterceptors(registry);
			registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
          // 这里创建  ResourceUrlProviderExposingInterceptor,使用的 ResourceUrlProvider
          // 由另外一个 bean 定义方法 #mvcResourceUrlProvider 提供
			registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider()));
			this.interceptors = registry.getInterceptors();
		}
		return this.interceptors.toArray();
	}

// requestMappingHandlerMapping() bean 定义中使用所有 getInterceptors() 定义的通用拦截器
// 		mapping.setInterceptors(getInterceptors());
// viewControllerHandlerMapping() bean 定义中使用所有 getInterceptors() 定义的通用拦截器
// 		handlerMapping.setInterceptors(getInterceptors());
// beanNameHandlerMapping() bean 定义中使用所有 getInterceptors() 定义的通用拦截器
// 		mapping.setInterceptors(getInterceptors());
// resourceHandlerMapping() bean 定义中使用所有 getInterceptors() 定义的通用拦截器
// 		handlerMapping.setInterceptors(getInterceptors());

2. 使用

DispatcherServlet#doDispatch请求处理主流程会先找到能处理该请求的Handler,以HandlerExecutionChain形式包装存在。这些HandlerExecutionChain来自某个HandlerMapping,而这些HandlerMapping就是Spring MVC配置中定义的那些HandlerMapping,它们在DispatcherServlet初始化阶段#initHandlerMappings执行时被从容器中获取。

DispatcherServlet#doDispatch得到HandlerExecutionChain之后,会调用其方法applyPreHandle以应用各个HandlerInterceptor对请求的前置处理逻辑。这其中就有ConversionServiceExposingInterceptor

	// HandlerExecutionChain 代码片段
    /**
	 * Apply preHandle methods of registered interceptors.
	 * @return {@code true} if the execution chain should proceed with the
	 * next interceptor or the handler itself. Else, DispatcherServlet assumes
	 * that this interceptor has already dealt with the response itself.
	 */
	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		HandlerInterceptor[] interceptors = getInterceptors();
		if (!ObjectUtils.isEmpty(interceptors)) {
			for (int i = 0; i < interceptors.length; i++) {
				HandlerInterceptor interceptor = interceptors[i];
				if (!interceptor.preHandle(request, response, this.handler)) {
					triggerAfterCompletion(request, response, null);
					return false;
				}
				this.interceptorIndex = i;
			}
		}
		return true;
	}

源代码解析

源代码版本 : spring-webmvc-5.1.5.RELEASE

package org.springframework.web.servlet.resource;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.Assert;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

/**
 * An interceptor that exposes the {@link ResourceUrlProvider} instance it
 * is configured with as a request attribute.
 *
 * @author Rossen Stoyanchev
 * @since 4.1
 */
public class ResourceUrlProviderExposingInterceptor extends HandlerInterceptorAdapter {

	/**
	 * Name of the request attribute that holds the {@link ResourceUrlProvider}.
	 */
	public static final String RESOURCE_URL_PROVIDER_ATTR = ResourceUrlProvider.class.getName();

	private final ResourceUrlProvider resourceUrlProvider;


	public ResourceUrlProviderExposingInterceptor(ResourceUrlProvider resourceUrlProvider) {
		Assert.notNull(resourceUrlProvider, "ResourceUrlProvider is required");
		this.resourceUrlProvider = resourceUrlProvider;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		request.setAttribute(RESOURCE_URL_PROVIDER_ATTR, this.resourceUrlProvider);
		return true;
	}

}

参考文章

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值