初期化SpringコンテナとBeanの作成プロセス

免責事項:この記事はブロガーオリジナル記事です、続くBY-SAのCC 4.0を著作権契約、複製、元のソースのリンクと、この文を添付してください。
このリンク: https://blog.csdn.net/TreeShu321/article/details/102757730

はじめに:いつもラフな理解を持ってBeanを作成し、初期化するためにSpringコンテナ上のさまざまな情報を読み取るために、今日の時間を取ることによって、次の初期化SpringコンテナとBeanの作成プロセスについての詳細を学びたいと思いました。

Springコンテナの初期化処理(ノート)

:AnnotationConfigApplicationContext例に
見るの継承グラフ:

ここに画像を挿入説明
ソースコード解析AnnotationConfigApplicationContext

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(UserConfig.class);

メインコードをAnnotationConfigApplicationContex

public AnnotationConfigApplicationContext(Class... annotatedClasses) {
        this(); 
		//2.注册bean配置类
        this.register(annotatedClasses);    
		//3.刷新上下文
        this.refresh();
    }

1.この()スキャナ及びリーダ豆を初期化します

public AnnotationConfigApplicationContext() {
        //在IOC容器中初始化一个 注解bean读取器AnnotatedBeanDefinitionReader
		this.reader = new AnnotatedBeanDefinitionReader(this);
		//在IOC容器中初始化一个 按类路径扫描注解bean的 扫描器
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

2.レジスタ(annotatedClasses)

タイプコンフィギュレーションレジスタ豆、豆AnnotationConfigApplicationContextコンテナ実装ノートregisterBean AnnotatedBeanDefinitionReader方法を渡す読み取り、特に次のソース:AnnotationConfigApplicationContext.javaレジスタ法

public void registerBean(Class<?> annotatedClass) {
		doRegisterBean(annotatedClass, null, null, null);
	}

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
 		//将Bean配置类信息转成容器中AnnotatedGenericBeanDefinition数据结构, AnnotatedGenericBeanDefinition继承
		//自BeanDefinition作用是定义一个bean的数据结构,下面的getMetadata可以获取到该bean上的注解信息
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		//@Conditional装配条件判断是否需要跳过注册
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		//解析bean作用域(单例或者原型),如果有@Scope注解,则解析@Scope,没有则默认为singleton
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		//作用域写回BeanDefinition数据结构, abd中缺损的情况下为空,将默认值singleton重新赋值到abd
		abd.setScope(scopeMetadata.getScopeName());
		//生成bean配置类beanName
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//通用注解解析到abd结构中,主要是处理Lazy, primary DependsOn, Role ,Description这五个注解
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
			//如果配置@Primary注解,则设置当前Bean为自动装配autowire时首选bean
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				//设置当前bean为延迟加载
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				//其他注解,则添加到abd结构中
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}
//根据beanName和bean定义信息封装一个BeanDefinitionHolder,其实就是一个 beanname和BeanDefinition的映射 
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		//创建代理对象 借助AnnotationConfigUtils工具类解析通用注解
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		// new ConcurrentHashMap<String, BeanDefinition>(256);用于保存注bean定义信息(beanname 和 beandefine映射)注册到IOC容器中
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

目的:コンフィグレーションBeanクラス自体の解決と登録を完了します。コンテナIOCキーと値のペアの形でそれを保存します。

3リフレッシュ()の更新状況

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// 1.刷新前的预处理
			prepareRefresh();

			// 2.获取刷新后的内部Bean工厂
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//3.BeanFactory的预准备工作
			prepareBeanFactory(beanFactory);

			try {
				//  BeanFactory准备工作完成后,可以做一些后置处理工作
				//4.空方法,用于在容器的子类中扩展
				postProcessBeanFactory(beanFactory);

				// 5. 执行BeanFactoryPostProcessor的方法,BeanFactory的后置处理器
				//在BeanFactory标准初始化之后执行的
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6. 注册BeanPostProcessor(Bean的后置处理器),用于拦截bean创建过程
				registerBeanPostProcessors(beanFactory);

				// 7. 初始化MessageSource组件(做国际化功能;消息绑定,消息解析).
				initMessageSource();

				// 8. 初始化事件派发器
				initApplicationEventMulticaster();

				//9.可以用于子类实现在容器刷新时自定义逻辑初始化
				onRefresh();

				// 10. 注册时间监听器,将ApplicationListener注册到容器中来
				registerListeners();

				// 11. 初始化所有剩下的单实例bean,单例bean在初始化容器时创建,懒加载在调用的时候创建
				finishBeanFactoryInitialization(beanFactory);

				//12. 完成BeanFactory的初始化创建工作,IOC容器就创建完成
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}

豆の作成プロセスの方法でリフレッシュ文脈語方法1-12、第11回を更新します。創造豆の具体的な方法は、我々は記事を参照することができ、コンテナの初期化プロセスとソースコード解析|春

おすすめ

転載: blog.csdn.net/TreeShu321/article/details/102757730