最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringMVC中的HandlerMappingIntrospector工具類詳解

 更新時間:2023年12月25日 10:07:05   作者:安迪源文  
這篇文章主要介紹了SpringMVC中的HandlerMappingIntrospector工具類詳解,這是一個Spring MVC助手類,用于集合應用所配置的HandlerMapping(url pattern和請求處理handler之間的映射)表,用于獲取針對某個請求的如下信息,需要的朋友可以參考下

HandlerMappingIntrospector工具類

概述

這是一個Spring MVC助手類,用于集合應用所配置的HandlerMapping(url pattern和請求處理handler之間的映射)表,用于獲取針對某個請求的如下信息 :

getMatchableHandlerMapping(javax.servlet.http.HttpServletRequest)

尋找能處理指定請求的HandlerMapping,如果找不到,返回null;如果找到的是一個MatchableHandlerMapping,則返回;如果找得到當并不是MatchableHandlerMapping,則拋出異常IllegalStateException。

getCorsConfiguration(javax.servlet.http.HttpServletRequest)

獲取針對指定請求的CORS配置,封裝為CorsConfiguration。如果不存在相應配置,返回null。

使用

作為CorsConfigurationSource使用

    // 配置類 WebMvcConfigurationSupport
	@Bean
	@Lazy
	public HandlerMappingIntrospector mvcHandlerMappingIntrospector() {
		return new HandlerMappingIntrospector();
	}

源代碼

源代碼版本 Spring Web MVC 5.1.5.RELEASE

package org.springframework.web.servlet.handler;
// 省略 imports
public class HandlerMappingIntrospector
		implements CorsConfigurationSource, ApplicationContextAware, InitializingBean {
	@Nullable
	private ApplicationContext applicationContext;
	@Nullable
	private List<HandlerMapping> handlerMappings;
	/**
	 * Constructor for use with ApplicationContextAware.
	 */
	public HandlerMappingIntrospector() {
	}
	/**
	 * Constructor that detects the configured {@code HandlerMapping}s in the
	 * given {@code ApplicationContext} or falls back on
	 * "DispatcherServlet.properties" like the {@code DispatcherServlet}.
	 * @deprecated as of 4.3.12, in favor of {@link #setApplicationContext}
	 */
	@Deprecated
	public HandlerMappingIntrospector(ApplicationContext context) {
		this.handlerMappings = initHandlerMappings(context);
	}
	/**
	 * Return the configured HandlerMapping's.
	 */
	public List<HandlerMapping> getHandlerMappings() {
		return (this.handlerMappings != null ? this.handlerMappings : Collections.emptyList());
	}
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) {
		this.applicationContext = applicationContext;
	}
   // InitializingBean 接口約定的方法,用于獲取容器中定義的所有類型為 HandlerMapping 的 bean,
   // 或者獲取缺省定義的類型為 HandlerMapping 的 bean
	@Override
	public void afterPropertiesSet() {
		if (this.handlerMappings == null) {
			Assert.notNull(this.applicationContext, "No ApplicationContext");
			this.handlerMappings = initHandlerMappings(this.applicationContext);
		}
	}
	/**
	 * Find the {@link HandlerMapping} that would handle the given request and
	 * return it as a {@link MatchableHandlerMapping} that can be used to test
	 * request-matching criteria.
	 * <p>If the matching HandlerMapping is not an instance of
	 * {@link MatchableHandlerMapping}, an IllegalStateException is raised.
	 * @param request the current request
	 * @return the resolved matcher, or {@code null}
	 * @throws Exception if any of the HandlerMapping's raise an exception
	 */
	@Nullable
	public MatchableHandlerMapping getMatchableHandlerMapping(HttpServletRequest request) throws Exception {
		Assert.notNull(this.handlerMappings, "Handler mappings not initialized");
		HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
		for (HandlerMapping handlerMapping : this.handlerMappings) {
			Object handler = handlerMapping.getHandler(wrapper);
			if (handler == null) {
				continue;
			}
			if (handlerMapping instanceof MatchableHandlerMapping) {
				return ((MatchableHandlerMapping) handlerMapping);
			}
			throw new IllegalStateException("HandlerMapping is not a MatchableHandlerMapping");
		}
		return null;
	}
    // 獲取某個 request 請求對應的 CorsConfiguration
    // 1. 從 handlerMappings 中找到該請求對應的 handler, 形式為 HandlerExecutionChain;
    // 2. 檢索 HandlerExecutionChain 中所有的 
	@Override
	@Nullable
	public CorsConfiguration getCorsConfiguration(HttpServletRequest request) {
		Assert.notNull(this.handlerMappings, "Handler mappings not initialized");
		HttpServletRequest wrapper = new RequestAttributeChangeIgnoringWrapper(request);
		for (HandlerMapping handlerMapping : this.handlerMappings) {
			HandlerExecutionChain handler = null;
			try {
				handler = handlerMapping.getHandler(wrapper);
			}
			catch (Exception ex) {
				// Ignore
			}
			if (handler == null) {
				continue;
			}
			if (handler.getInterceptors() != null) {
				for (HandlerInterceptor interceptor : handler.getInterceptors()) {
					if (interceptor instanceof CorsConfigurationSource) {
						return ((CorsConfigurationSource) interceptor).getCorsConfiguration(wrapper);
					}
				}
			}
			if (handler.getHandler() instanceof CorsConfigurationSource) {
				return ((CorsConfigurationSource) handler.getHandler()).getCorsConfiguration(wrapper);
			}
		}
		return null;
	}
	private static List<HandlerMapping> initHandlerMappings(ApplicationContext applicationContext) {
       // 獲取容器中所有類型為 HandlerMapping 的 bean
		Map<String, HandlerMapping> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(
				applicationContext, HandlerMapping.class, true, false);
		if (!beans.isEmpty()) {
			List<HandlerMapping> mappings = new ArrayList<>(beans.values());
			AnnotationAwareOrderComparator.sort(mappings);
			return Collections.unmodifiableList(mappings);
		}
       // 容器中不存在類型為 HandlerMapping 的 bean,
       // 此時使用 initFallback 創(chuàng)建 DispatcherServlet.properties 文件中
       // 缺省定義的類型為 HandlerMapping 的 bean
		return Collections.unmodifiableList(initFallback(applicationContext));
	}
	private static List<HandlerMapping> initFallback(ApplicationContext applicationContext) {
		Properties props;
		String path = "DispatcherServlet.properties";
		try {
			Resource resource = new ClassPathResource(path, DispatcherServlet.class);
			props = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load '" + path + "': " + ex.getMessage());
		}
		String value = props.getProperty(HandlerMapping.class.getName());
		String[] names = StringUtils.commaDelimitedListToStringArray(value);
		List<HandlerMapping> result = new ArrayList<>(names.length);
		for (String name : names) {
			try {
				Class<?> clazz = ClassUtils.forName(name, DispatcherServlet.class.getClassLoader());
              // 使用容器創(chuàng)建 bean,該動作會使所創(chuàng)建的 bean 經歷相應的生命周期處理,比如初始化,屬性設置等等  
				Object mapping = applicationContext.getAutowireCapableBeanFactory().createBean(clazz);
				result.add((HandlerMapping) mapping);
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException("Could not find default HandlerMapping [" + name + "]");
			}
		}
		return result;
	}
	/**
	 * Request wrapper that ignores request attribute changes.
     * 定義一個給當前 HandlerMappingIntrospector 使用的 HttpServletRequestWrapper,
     * 其方法 setAttribute 實現(xiàn)為空,主要是用于避免屬性修改,也就是保持對所訪問的 request 不做修改
	 */
	private static class RequestAttributeChangeIgnoringWrapper extends HttpServletRequestWrapper {
		public RequestAttributeChangeIgnoringWrapper(HttpServletRequest request) {
			super(request);
		}
		@Override
		public void setAttribute(String name, Object value) {
			// Ignore attribute change...
		}
	}
}

到此這篇關于SpringMVC中的HandlerMappingIntrospector工具類詳解的文章就介紹到這了,更多相關HandlerMappingIntrospector工具類內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java中使用Graphics2D繪圖方法小結

    Java中使用Graphics2D繪圖方法小結

    文章介紹了使用Java的Graphics2D類繪制圖形和文本的方法,包括字體安裝、簡單圖形樣式繪制、文本添加以及文件管理
    2025-05-05
  • Java多線程并發(fā)生產者消費者設計模式實例解析

    Java多線程并發(fā)生產者消費者設計模式實例解析

    這篇文章主要介紹了Java多線程并發(fā)生產者消費者設計模式實例解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-03-03
  • Feign超時 在yml文件里的配置方式

    Feign超時 在yml文件里的配置方式

    這篇文章主要介紹了Feign超時 在yml文件里的配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • Spring Boot延遲執(zhí)行實現(xiàn)方法

    Spring Boot延遲執(zhí)行實現(xiàn)方法

    本文介紹了在Spring Boot項目中延遲執(zhí)行方法的實現(xiàn),以及延遲執(zhí)行下聲明式事務和編程式事務的使用情況,感興趣的朋友一起看看吧
    2020-12-12
  • java如何用遞歸生成樹形結構

    java如何用遞歸生成樹形結構

    作者分享了自己在使用腳本之家資源進行編程時的經驗,包括準備實體對象、測試數(shù)據(jù)、構造樹形結構遞歸函數(shù)、測試以及輸出結果等步驟,作者希望這些經驗能對大家有所幫助,并鼓勵大家支持腳本之家
    2025-03-03
  • Spring基于注解讀取外部配置文件

    Spring基于注解讀取外部配置文件

    這篇文章主要介紹了Spring基于注解讀取外部配置文件,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-12-12
  • idea如何自動生成serialVersionUID

    idea如何自動生成serialVersionUID

    這篇文章主要介紹了idea如何自動生成serialVersionUID,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • Java分頁簡介_動力節(jié)點Java學院整理

    Java分頁簡介_動力節(jié)點Java學院整理

    這篇文章主要為大家詳細介紹了Java分頁簡介的相關資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-08-08
  • Java校驗銀行卡是否正確的核心代碼

    Java校驗銀行卡是否正確的核心代碼

    這篇文章主要介紹了Java校驗銀行卡是否正確的核心代碼,需要的朋友可以參考下
    2017-01-01
  • Java虛擬機運行時棧的棧幀

    Java虛擬機運行時棧的棧幀

    本節(jié)將會介紹一下Java虛擬機棧中的棧幀,會對棧幀的組成部分(局部變量表、操作數(shù)棧、動態(tài)鏈接、方法出口)分別進行介紹,最后還會通過javap命令反解析編譯后的.class文件,進行分析方法執(zhí)行時的局部變量表、操作數(shù)棧等
    2021-09-09

最新評論

峡江县| 巴青县| 寿光市| 长白| 柘荣县| 黄山市| 荔波县| 怀安县| 灌云县| 邹城市| 长沙县| 碌曲县| 洛隆县| 五河县| 柞水县| 桐柏县| 名山县| 满城县| 托里县| 湟源县| 梅河口市| 东台市| 施秉县| 利川市| 蒙城县| 伊金霍洛旗| 台州市| 察隅县| 太仆寺旗| 广东省| 图们市| 安远县| 上蔡县| 安泽县| 杨浦区| 姜堰市| 罗甸县| 郯城县| 呈贡县| 甘洛县| 彝良县|