Heim > Java > javaLernprogramm > SpringBoot spring.factories lädt Timing-Quellcode-Analyse

SpringBoot spring.factories lädt Timing-Quellcode-Analyse

WBOY
Freigeben: 2023-05-17 21:31:04
nach vorne
1396 Leute haben es durchsucht

Die Rolle von spring.factories

Dies ähnelt der SPI-Funktion in Java. Wenn SpringBoot startet, liest es die META-INF/spring.factories-Dateien unter allen JAR-Paketen;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();
	}
Nach dem Login kopieren

其中方法getSpringFactoriesInstances( ApplicationContextInitializer.class) 是用于获取Spring中指定类实例用的;并且获取的时候是根据读取整个项目中文件路径为META-INF/spring.factories 中的内容实例化对应的实例类的;

例如这里的ApplicationContextInitializer 是一个接口,那么应该实例化哪些他的实现类呢?那就找META-INF/spring.factories文件 ; 那么我们在spring-boot:2.1.0jar包中找到了这个文件

SpringBoot spring.factories lädt Timing-Quellcode-Analyse

读取到需要实例化的实现类为

org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer
Nach dem Login kopieren

并且还在spring-boot-autoconfigure-2.1.0.RELEASE.jar中找到了这个文件

SpringBoot spring.factories lädt Timing-Quellcode-Analyse

那么文件中的两个实现类也会被实例化;加上上面4个总共有6个

org.springframework.boot.autoconfigure.SharedMetadataReaderFactoryContextInitializer,\
org.springframework.boot.autoconfigure.logging.ConditionEvaluationReportLoggingListener
Nach dem Login kopieren

SpringBoot spring.factories lädt Timing-Quellcode-Analyse

可以看到不仅仅只是把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;
	}
Nach dem Login kopieren

方法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;
	}
Nach dem Login kopieren

实例化的过程如果,没有什么特别需要讲解的;

上面有个方法 AnnotationAwareOrderComparator.sort(instances);是用来排序所有实例的; 实现类需要实现 接口Ordered ; getOrder返回的值越小,优先级更高

用法

知道spring.factories的用法之后, 那么我们就可以利用这个特性实现自己的目的;

例如我们也可以写一个接口类ApplicationContextInitializer

und Speichern Sie die Dateien in. Die den Schnittstellen/abstrakten Klassen entsprechenden Implementierungsklassen werden einander zugeordnet, und die entsprechenden Implementierungsklassen können bei Bedarf instanziiert werden🎜🎜Lassen Sie uns den Quellcode analysieren und die Verwendungsszenarien von spring.factoriessehen >🎜🎜 Quellcode-Analyse🎜🎜Starten Sie SpringApplication und schauen Sie sich die Konstruktionsmethode an🎜rrreee🎜Die Methode getSpringFactoriesInstances(ApplicationContextInitializer.class) wird verwendet, um die angegebene Klasseninstanz in Spring abzurufen basiert auf dem Lesen des gesamten Dateipfads im Projekt ist der Inhalt in META-INF/spring.factories, der die entsprechende Instanzklasse instanziiert 🎜🎜Zum Beispiel der ApplicationContextInitializer Hier ist eine Schnittstelle, also sollte sie instanziiert werden. Welche anderen Implementierungsklassen sollten transformiert werden? Suchen Sie dann nach der Datei META-INF/spring.factories; dann haben wir diese Datei im spring-boot:2.1.0jar-Paket gefunden🎜🎜SpringBoot spring.factories lädt Timing-Quellcode-Analyse🎜🎜Lesen Sie, dass die Implementierungsklasse sein muss instanziiert ist 🎜rrreee🎜Und fand diese Datei auch in spring-boot-autoconfigure-2.1.0.RELEASE.jar🎜🎜SpringBoot spring.factories Loading Timing Source Code Analysis🎜🎜Dann werden auch die beiden Implementierungsklassen in der Datei instanziiert; plus die oben genannten 4 gibt es eine insgesamt 6 🎜rrreee🎜SpringBoot spring.factories lädt Timing-Quellcode-Analyse 🎜🎜Ja, achten Sie darauf, dass nicht nur die Instanzklassen von org.springframework.context.ApplicationContextInitializer analysiert werden, sondern dass alle anderen Klassen beim nächsten Mal instanziiert werden müssen es direkt aus dem Speicher; 🎜🎜Nachdem die Instanzklasse im obigen Prozess abgerufen wurde, ist der nächste Schritt der Instanziierungsprozess 🎜rrreee🎜Die Methode createSpringFactoriesInstances ist der Prozess zum Erstellen einer Instanz Geben Sie die entsprechende Schnittstellenklasse org.springframework.context.ApplicationContextInitializer ein und instanziieren Sie dann die entsprechende oben gefundene Implementierungsklasse eine Methode AnnotationAwareOrderComparator.sort(instances);, die zum Sortieren aller Instanzen verwendet wird; die Implementierungsklasse muss die Schnittstelle Ordered implementieren, je kleiner der von getOrder zurückgegebene Wert ist; Die Priorität ist höher🎜

Nutzung

🎜Nachdem wir die Verwendung von spring.factories kennen, können wir diese Funktion verwenden, um unsere eigenen Ziele zu erreichen; 🎜🎜Zum Beispiel können wir das auch Schreiben Sie eine Schnittstellenimplementierungsklasse der Klasse ApplicationContextInitializer. 🎜

Das obige ist der detaillierte Inhalt vonSpringBoot spring.factories lädt Timing-Quellcode-Analyse. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:yisu.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage