91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

SpringBoot?spring.factories加載時機源碼分析

發布時間:2023-03-13 16:45:15 來源:億速云 閱讀:270 作者:iii 欄目:開發技術

這篇文章主要介紹“SpringBoot spring.factories加載時機源碼分析”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“SpringBoot spring.factories加載時機源碼分析”文章能幫助大家解決問題。

spring.factories作用

這個類似于Java中的SPI功能,SpringBoot啟動的時候會讀取所有jar包下面的META-INF/spring.factories文件;

并且將文件中的 接口/抽象類 對應的實現類都對應起來,并在需要的時候可以實例化對應的實現類

下面我們來分析一下源碼看看spring.factories的使用場景

源碼解析

啟動SpringApplication,看看構造方法

	public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
		this.resourceLoader = resourceLoader;
		Assert.notNull(primarySources, "PrimarySources must not be null");
		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
		this.webApplicationType = WebApplicationType.deduceFromClasspath();
		setInitializers((Collection) getSpringFactoriesInstances(
				ApplicationContextInitializer.class));
		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
		this.mainApplicationClass = deduceMainApplicationClass();
	}

其中方法getSpringFactoriesInstances( ApplicationContextInitializer.class) 是用于獲取Spring中指定類實例用的;并且獲取的時候是根據讀取整個項目中文件路徑為META-INF/spring.factories 中的內容實例化對應的實例類的;

例如這里的ApplicationContextInitializer 是一個接口,那么應該實例化哪些他的實現類呢?那就找META-INF/spring.factories文件 ; 那么我們在spring-boot:2.1.0jar包中找到了這個文件

SpringBoot?spring.factories加載時機源碼分析

讀取到需要實例化的實現類為

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

并且還在spring-boot-autoconfigure-2.1.0.RELEASE.jar中找到了這個文件

SpringBoot?spring.factories加載時機源碼分析

那么文件中的兩個實現類也會被實例化;加上上面4個總共有6個

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener

SpringBoot?spring.factories加載時機源碼分析

可以看到不僅僅只是把org.springframework.context.ApplicationContextInitializer 的實例類解析了出來;而是所有的都解析了出來并且保存下來了.下次其他的類需要被實例化的時候就可以直接從內存里面拿了;

上面過程拿到了實例類之后,接下來就是實例化的過程了

	private <T> Collection<T> getSpringFactoriesInstances(Class<T> type,
			Class<?>[] parameterTypes, Object... args) {
		ClassLoader classLoader = getClassLoader();
		// Use names and ensure unique to protect against duplicates
		Set<String> names = new LinkedHashSet<>(
				SpringFactoriesLoader.loadFactoryNames(type, classLoader));
		List<T> instances = createSpringFactoriesInstances(type, parameterTypes,
				classLoader, args, names);
		AnnotationAwareOrderComparator.sort(instances);
		return instances;
	}

方法createSpringFactoriesInstances就是創建實例的過程;可以看到傳入了對應的接口類org.springframework.context.ApplicationContextInitializer ;接下來就會實例化 上面找到了對應的實現類;

	private <T> List<T> createSpringFactoriesInstances(Class<T> type,
			Class<?>[] parameterTypes, ClassLoader classLoader, Object[] args,
			Set<String> names) {
		List<T> instances = new ArrayList<>(names.size());
		for (String name : names) {
			try {
				Class<?> instanceClass = ClassUtils.forName(name, classLoader);
				Assert.isAssignable(type, instanceClass);
				Constructor<?> constructor = instanceClass
						.getDeclaredConstructor(parameterTypes);
				T instance = (T) BeanUtils.instantiateClass(constructor, args);
				instances.add(instance);
			}
			catch (Throwable ex) {
				throw new IllegalArgumentException(
						"Cannot instantiate " + type + " : " + name, ex);
			}
		}
		return instances;
	}

實例化的過程如果,沒有什么特別需要講解的;

上面有個方法 AnnotationAwareOrderComparator.sort(instances);是用來排序所有實例的; 實現類需要實現 接口Ordered ; getOrder返回的值越小,優先級更高

用法

知道spring.factories的用法之后, 那么我們就可以利用這個特性實現自己的目的;

例如我們也可以寫一個接口類ApplicationContextInitializer的實現類。

關于“SpringBoot spring.factories加載時機源碼分析”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

开原市| 阜宁县| 莱西市| 西宁市| 遵义市| 鲁甸县| 德化县| 黔东| 保康县| 宜城市| 察哈| 沙坪坝区| 清苑县| 广宁县| 东光县| 灵山县| 临城县| 宜黄县| 正宁县| 江都市| 分宜县| 信丰县| 孟津县| 溆浦县| 湛江市| 沂南县| 大洼县| 保定市| 峨眉山市| 砚山县| 淮阳县| 新邵县| 安庆市| 奎屯市| 荆门市| 大宁县| 崇文区| 武穴市| 加查县| 江阴市| 榆林市|