[フレームソースコード] SpringBootコアソースコード解釈の自動構成ソースコード解析

ここに画像の説明を挿入

SpringBoot が普及する前は、プログラマーは主にSSM框架WEB バックエンド開発に統合を使用していました。この方法は手動で多数のパッケージを導入したり、多数のXMLファイルを設定したりする必要があり、非常に煩雑であり、環境構築だけでも時間がかかります。

この種の SSM の煩雑な XML 構成に基づいて、後に SpringBoot が派生しました。SpringBoot の自動ロードにより、開発者の構成に関する情報が大幅に簡素化されます。

質問: SpringBoot 自動構成とは何ですか?

  • Spring コンテナが開始されると、一部の自動構成クラスが@ConditionalIOC コンテナ内のアノテーションを通じて自動アセンブリされます。
  • 手動で注入する必要がないため、開発が簡素化され、面倒な構成が節約されます。
  • 自動構成の関連作業は@SpringBootApplicationこの

この注釈を見てみましょう@SpringBootApplication

@Target({
    
    ElementType.TYPE})  //注解的作用范围,用在类,接口,注解等上面
@Retention(RetentionPolicy.RUNTIME) //注解生命周期,runtime,保留在运行时期
@Documented //可以被文档化
@Inherited //可以被子类继承
@SpringBootConfiguration  //里面是@Configuration属于配置类
@EnableAutoConfiguration  //启动自动配置功能
//配置扫描包
@ComponentScan(
    excludeFilters = {
    
    @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication

@SpringBootApplication は、いくつかのコア アノテーションで構成される複合アノテーションです。

  • @SpringBootConfiguration
    • 内部には @Configuration があり、これは構成クラスを表し、メイン プログラム クラスも構成クラスであることを示します。
  • @EnableAutoConfiguration
    • @AutoConfigurationPackage は、指定されたパッケージの下にあるすべてのコンポーネントをコンテナーにインポートします
    • @AutoConfigurationPackage アノテーションには @Import({Registrar.class}) アノテーションがあり、これを通じて自動構成パッケージが行われます。
  • @ComponentScan
    • スキャンするコンポーネントを指定します。デフォルトでは、メイン プログラムが配置されているパッケージとそのサブパッケージがスキャンされます。

その核心はこのアノテーションにあり@EnableAutoConfiguration、自動構成をロードするためのクラス情報が含まれています。

@EnableAutoConfiguration アノテーションのコアコンテンツ

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage //自动配置包
@Import(AutoConfigurationImportSelector.class) //通过import导入满足条件的bean,并加载到spring的ioc容器里面
public @interface EnableAutoConfiguration 

@AutoConfigurationPackage アノテーションのコアコンテンツ

  • Registrar の役割はパッケージをスキャンすることです。デフォルトでは、パッケージ内のすべてのクラスと、メイン クラスが配置されているサブパッケージがコンテナ内にスキャンされます。
  • では、Springboot プロジェクトを開発するときに、なぜメインクラスを最も外側のディレクトリに配置する必要があるのでしょうか。そうしないと、正しいアノテーションクラスが見つからなくなります。
@Import(AutoConfigurationPackages.Registrar.class) //把Registrar导入到spring容器里面

コア ロジックはこのロジックであり、後でデバッグ用にブレークポイントを設定します。

		//获取主程序所在的目录为位置,metadata是元注解信息
		@Override
		public void registerBeanDefinitions(AnnotationMetadata metadata,
				BeanDefinitionRegistry registry) {
    
    
			register(registry, new PackageImport(metadata).getPackageName());
		}

@Import(AutoConfigurationImportSelector.class)次に、この中でどのような操作が行われたかを見てみましょう。その核心は、インポートを通じて条件を満たすBeanをインポートし、Springbootアプリケーションの@Configurationを満たすクラスをSpring IOCコンテナにロードすることです。

	//用于实现动态注册Bean的功能,【批量】导入对象到容器里,根据条件动态地选择需要注册的Bean,并加入Spring容器
  //实现ImportSelector接口,这个接口的selectImports方法会返回一个String数组,数组中的值就是要添加的组件的全类名
  public String[] selectImports(AnnotationMetadata annotationMetadata) {
    
    
		if (!isEnabled(annotationMetadata)) {
    
    
			return NO_IMPORTS;
		}
    //加载元数据信息
		AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader
				.loadMetadata(this.beanClassLoader);
    //获取需要自动装载的类的信息
		AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(
				autoConfigurationMetadata, annotationMetadata);
		return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
	}

getAutoConfigurationEntry()さて、このメソッドのロジックを見てみましょう。このメソッドは主に、指定されたアノテーション メタデータに従って自動構成されたエントリを取得することを目的としています。

protected AutoConfigurationEntry getAutoConfigurationEntry(
			AutoConfigurationMetadata autoConfigurationMetadata,
			AnnotationMetadata annotationMetadata) {
    
    
  	//判断是否启用了自动配置
		if (!isEnabled(annotationMetadata)) {
    
    
			return EMPTY_ENTRY;
		}
		AnnotationAttributes attributes = getAttributes(annotationMetadata);
  	//获取候选自动配置类列表
		List<String> configurations = getCandidateConfigurations(annotationMetadata,
				attributes);
  	//去除重复的自动配置类
		configurations = removeDuplicates(configurations);
  	//获取需要排除的自动配置类列表
		Set<String> exclusions = getExclusions(annotationMetadata, attributes);
  	//检查是否存在需要排除的自动配置类
		checkExcludedClasses(configurations, exclusions);
  	//将需要排除的类从自动配置类列表中移除
		configurations.removeAll(exclusions);
  	//获取配置类过滤器,对候选自动配置类列表进行过滤
		configurations = filter(configurations, autoConfigurationMetadata);
  	//触发自动配置导入事件,并返回一个新的自动配置条目
		fireAutoConfigurationImportEvents(configurations, exclusions);
		return new AutoConfigurationEntry(configurations, exclusions);
	}

ここで、このファイルgetCandidateConfigurations()にアクセスしてすべての構成情報を取得するというコア ロジックを見てみましょう。META-INF/spring.factories

	protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
			AnnotationAttributes attributes) {
    
    
		List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
				getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
		Assert.notEmpty(configurations,
				"No auto configuration classes found in META-INF/spring.factories. If you "
						+ "are using a custom packaging, make sure that file is correct.");
		return configurations;
	}
	public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";

さて、デバッグしてソースコードのプロセスを見てみましょう。

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入ここに画像の説明を挿入
ここに画像の説明を挿入ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

ここに画像の説明を挿入
ここに画像の説明を挿入

さて、SpringBoot の自動ロードのプロセス全体を要約しましょう。

  • まず、メタデータ情報を読み込みます
  • 自動ロードする必要があるクラスに関する情報を取得する
    • 自動構成が有効かどうかを確認する
    • 候補となる自動構成クラスのリストを取得する
    • 除外する必要がある自動構成クラスのリストを取得します。
    • 除外する必要がある自動構成クラスを確認する
    • 自動構成クラスのリストから除外する必要があるクラスを削除します。
    • 構成クラス フィルターを取得して、候補自動構成クラスのリストをフィルター処理します。
    • autoconfig インポート イベントをトリガーし、新しい autoconfig エントリを返します。
  • 登録されているBean定義のリスト

おすすめ

転載: blog.csdn.net/weixin_47533244/article/details/130763568