Spring容器初始化和bean创建过程

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/TreeShu321/article/details/102757730

前言:一直想详细了解下Spring容器初始化和bean创建过程,今天抽空通过翻阅各种资料,对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.this() 初始化bean读取器和扫描器

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

2. register(annotatedClasses)

注册bean配置类, AnnotationConfigApplicationContext容器通过AnnotatedBeanDefinitionReader的registerBean方法实现注解bean的读取,具体源码如下:AnnotationConfigApplicationContext.java中register方法

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 refresh()刷新上下文

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();
			}
		}
	}

refresh刷新上下文字方法1到12,bean的创建过程在第11个方法。具体bean的创建方法我们可以参考这篇文章Spring|容器初始化流程及源码分析

猜你喜欢

转载自blog.csdn.net/TreeShu321/article/details/102757730