ホームページ  >  記事  >  Java  >  SpringBoot spring.factories 読み込みタイミングのソースコード解析

SpringBoot spring.factories 読み込みタイミングのソースコード解析

WBOY
WBOY転載
2023-05-17 21:31:041348ブラウズ

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 読み込みタイミングのソースコード解析#ファイル内の 2 つの実装クラスもインスタンス化され、上記の 4 つに加えて、合計 6 つになります##

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

#org.springframework.context.ApplicationContextInitializer

のインスタンス クラスが解析されるだけでなく、すべてが解析されて保存されることがわかります。他のクラスは次回それを必要とします。メモリから直接取得する; SpringBoot spring.factories 読み込みタイミングのソースコード解析

上記のプロセスでインスタンス クラスを取得したら、次のステップはインスタンス化プロセスです

	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;
	}
MethodcreateSpringFactoriesInstances

作成するプロセスですインスタンス; 対応するインターフェイス クラスが

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 によって返される値が小さいほど、優先順位が高くなります。

Usagespring.factories の使用法を理解した後、この機能を使用して次のことができます。独自の目的を達成します。

たとえば、インターフェイス クラス

ApplicationContextInitializer

の実装クラスを作成することもできます。

以上がSpringBoot spring.factories 読み込みタイミングのソースコード解析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。