Spring IOCソースコード分析(注釈に基づく)

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
		this();
		register(componentClasses);
		refresh();
}

レビュー

前のセクションの基本的なプロセスを確認してください。

this()メソッドの主な機能は、SpringIOCコンテナの初期化操作を完了することです。これには、次の点が含まれます。

  1. BeanDefinitionReader、Bean定義リーダーを作成します。リーダーは、対応するiocコンテナインスタンスを読み取ります。beanFactoryを取得します。
  2. IOCコンテナBeanに注入する必要がある条件を計算します
  3. beanFactoryの依存関係と自動解決手順を設定します。
  4. benaの範囲、beanの役割などを含む、IOCコンテナの後処理手順を提供します。
  5. IOC内部Beanの登録を完了します。レジストリホルダーBeanDefinitionHolderに登録済み
  6. BeanDefinitionScanner、Bean定義スキャナーを作成します。IOCコンテナ内のBeanをスキャンします。次に、この時点でスキャンする必要のないBeanを除外します。@ Service、@ Controllerなど。これはIOC内部Beanの初期化であるためです。

次に、register(componentClasses)メソッドを見てみましょう。この時点で、自分で定義されたBeanを取得します。componentClasses= AppConfig.class。

register(componentClasses)

	public void register(Class<?>... componentClasses) {
		Assert.notEmpty(componentClasses, "At least one component class must be specified");
		StartupStep registerComponentClass = this.getApplicationStartup().start("spring.context.component-classes.register")
				.tag("classes", () -> Arrays.toString(componentClasses));
		this.reader.register(componentClasses);
		registerComponentClass.end();
	}

登録はリーダーで行われます。上記は単なるファサード方法です。AnnotatedBeanDefinitionReaderのregister()メソッドが呼び出されます。これは実際にはファサード方式です。

public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}

最終的な実装はdoRegisterBeanメソッドにあります。

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {
		//1 创建了通用的bean定义实例。
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			//2 这里判断要不要将该bean添加到IOC容器当中。一般和@Conditional注解有关
			return;
		}

		abd.setInstanceSupplier(supplier);
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		//3 scopeMetadata.getScopeName()=singleton 在这里设置了单例模式。默认为单例
		abd.setScope(scopeMetadata.getScopeName());
		//4 获取bean的名称,默认首字母小写
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//这里对bean做一些处理。设置是否懒加载、是否私有、设置依赖关系、设置bean角色以及bean的描述。此时的设置保存在abd中
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		if (customizers != null) {
			for (BeanDefinitionCustomizer customizer : customizers) {
				customizer.customize(abd);
			}
		}
		//创建bean定义持有者。bean的描述
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		//根据bean的作用域设置代理模式,获取代理之后的definitionHolder。
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

最後に、Beanの登録はBeanDefinitionReaderUtilsのregisterBeanDefinition()メソッドで完了します。実際、これはファサード方式でもあります。DeaultListableFactoryで完了しました。

結局、Bean情報は主に次のコレクションにあります。

this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
DeaultListableFactoryに2つのフィールドがありますprivatefinal 
Map <String、BeanDefinition> beanDefinitionMap = new ConcurrentHashMap <>(256); key = beanName、value = BeanDefinition priate 
volatile List <String> beanDefinitionNames = new ArrayList <>(256);このリストコレクション主に豆の名前をすべて保存します。

 

おすすめ

転載: blog.csdn.net/GoSaint/article/details/109996871