Spring源码之容器启动

概述

在Spring框架中,启动时需要扫描并加载应用程序中的Bean。本文将探究Spring 5.3.0版本中基于注解的Bean扫描过程,帮助读者深入了解Spring框架的工作原理.

容器启动

首先让我们使用基于注解的方式启动Spring容器,传入一个配置类,如下代码:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);

让我们进入该构造方法看下,很简洁只有三行代码

// 创建一个新的AnnotationConfigApplicationContext对象
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    // 调用无参构造函数
    this();
    // 注册配置类
    register(componentClasses);
    // 刷新容器,完成容器的初始化和启动过程
    refresh();
}

this()

在Java中,子类继承了父类的属性和方法,而构造函数也是类的一部分。
由于 AnnotationConfigApplicationContext 继承 GenericApplicationContext,所以会先调用GenericApplicationContext的无参构造.

// AnnotationConfigApplicationContext的无参构造
public AnnotationConfigApplicationContext() {
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
// GenericApplicationContext的无参构造
public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}
// 综上this()方法
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
this.beanFactory = new DefaultListableBeanFactory();
  • AnnotatedBeanDefinitionReader
    Spring框架中的一个类,用于读取并解析带有注解的Bean定义。它可以通过扫描类路径、指定包名或通过指定类来读取带有注解的Bean定义.
  • ClassPathBeanDefinitionScanner
    Spring框架中的一个类,用于在类路径上扫描并解析Bean定义。它可以根据指定的包名或类来扫描对应的类,并将其转换为Bean定义。它使用了BeanDefinitionRegistry来注册和管理扫描到的Bean定义.
  • DefaultListableBeanFactory
    Spring框架中的一个类,实现了BeanDefinitionRegistry和ConfigurableListableBeanFactory接口。它是Spring的默认的可列表的Bean工厂实现类,负责注册、管理和获取Bean实例.

1.this.reader = new AnnotatedBeanDefinitionReader(this);
该实例化AnnotatedBeanDefinitionReader时会构造用于注册注解驱动的Bean后置处理器和相关的解析器。
2.this.scanner = new ClassPathBeanDefinitionScanner(this);
该实例化会添加默认的注解类型过滤this.includeFilters.add(new AnnotationTypeFilter(Component.class));后续文件扫描会使用

// 进入方法
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
// 继续进入
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
	registerAnnotationConfigProcessors(registry, null);
}
// 提前注册必要的后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		// 检查并设置DefaultListableBeanFactory的依赖比较器和自动装配候选解析器
		// 以确保它们是AnnotationAwareOrderComparator和ContextAnnotationAutowireCandidateResolver的实例
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		// 用于保存注册的BeanDefinitionHolder的集合
		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

		// 注册ConfigurationClassPostProcessor(用于处理@Configuration注解和相关注解的后置处理器)
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 注册AutowiredAnnotationBeanPostProcessor(用于处理@Autowired和相关注解的后置处理器)
		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 检查并添加CommonAnnotationBeanPostProcessor(处理JSR-250注解的后置处理器)
		// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
		if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 检查并添加PersistenceAnnotationBeanPostProcessor(处理JPA注解的后置处理器)
		// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
		if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition();
			try {
				def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
						AnnotationConfigUtils.class.getClassLoader()));
			}
			catch (ClassNotFoundException ex) {
				throw new IllegalStateException(
						"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
			}
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		// 注册EventListenerMethodProcessor(用于处理@EventListener注解的后置处理器)
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
		}

		// 注册DefaultEventListenerFactory(用于创建事件监听器的工厂Bean)
		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
		}

		return beanDefs;
	}

在这里插入图片描述

register(componentClasses)

向AnnotationConfigApplicationContext或其子类注册配置类的方法。它接受一个或多个配置类作为参数,将这些配置类转换为BeanDefinition并注册到容器中。
进入方法

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

进入this.reader.register(componentClasses);

// 遍历传入的componentClasses参数,其中每个元素代表一个配置类
public void register(Class<?>... componentClasses) {
		for (Class<?> componentClass : componentClasses) {
			registerBean(componentClass);
		}
	}
// 我们这里只有一个class -> MainConfig.class

让我们进入registerBean(componentClass);

doRegisterBean(beanClass, null, null, null, null);
// 继续进入
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
			@Nullable BeanDefinitionCustomizer[] customizers) {
		// 1.创建一个AnnotatedGenericBeanDefinition对象,用于保存Bean定义的元数据
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
		// 2.检查是否应该跳过当前Bean定义,根据条件表达式的结果判断
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
		
		abd.setInstanceSupplier(supplier);
		// 3.解析Bean的作用域信息,并设置到Bean定义中
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		// 4.生成Bean的名称,如果没有指定名称则由BeanNameGenerator生成
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		// 5.处理常见的定义注解,如@Primary、@Lazy等(将信息封装进BeanDefinition)
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		// 6.处理限定符注解,如@Qualifier、@Primary、@Lazy等
		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);
			}
		}
		// 7.创建一个Bean定义持有者,用于保存Bean定义和名称
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		// 8.根据作用域信息应用代理模式,如果需要创建代理则应用ScopedProxyMode
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		// 9.注册Bean定义到BeanDefinitionRegistry中
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

总结上述流程,reader就是将配置类转化为BeanDefinition,然后我们进入下一步

// 注册BeanDefinition到BeanDefinitionRegistry中
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
// 进入方法
public static void registerBeanDefinition(
		BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
		throws BeanDefinitionStoreException {

	// 注册主要名称的Bean定义
	String beanName = definitionHolder.getBeanName();
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

	// 注册别名
	String[] aliases = definitionHolder.getAliases();
	if (aliases != null) {
		for (String alias : aliases) {
			registry.registerAlias(beanName, alias);
		}
	}
}

现在让我们进入方法
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

// 这里我们只看关键的代码,其他省略
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {
...
// 获取已存在的BeanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);	
if (existingDefinition != null) {
	...
	// 将当前BeanDefinition替换已存在的BeanDefinition
	this.beanDefinitionMap.put(beanName, beanDefinition);		
}else{
	// 如果不存在同名的BeanDefinition,将当前BeanDefinition注册到beanDefinitionMap中
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				// 如果已经开始创建Bean,则使用同步块来添加BeanDefinition,以确保线程安全
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
				// 当前我们会进入这个条件中-> 将bean定义放入beanDefinitionMap中
				// 如果还在启动阶段,直接添加BeanDefinition到beanDefinitionMap中
				// Still in startup registration phase
				this.beanDefinitionMap.put(beanName, beanDefinition);
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}
	}
}

如下图配置类MainConfig已经被注册到BedifinationMap中
在这里插入图片描述

refresh()

刷新容器,完成容器的初始化和启动过程.具体看下该方法都做了什么

public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
		
			// 1.刷新预处理,初始化环境变量,验证环境变量必须要有的属性
			prepareRefresh();

			// 2.主要获取一个Bean工厂,这里是DefaultListableBeanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3.为使用该上下文准备Bean工厂
			prepareBeanFactory(beanFactory);

			try {
				// 4.在上下文子类中允许对Bean工厂进行后处理
				postProcessBeanFactory(beanFactory);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// 5.调用Bean的后置处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// 6.注册我们自己定义的bean后置处理器
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// 7.初始化国际化资源处理器
				initMessageSource();

				// 8.初始化一个事件广播器,即事件监听器管理
				initApplicationEventMulticaster();

				// 9.空方法
				onRefresh();

				// 10.注册监听器,系统的以及程序员自定义的(实现接口ApplicationListener或方法@EventListener)
				registerListeners();

				// 11.实例化非懒加载到单例Bean
				finishBeanFactoryInitialization(beanFactory);

				// 12.最后一步:发布相应的事件
				finishRefresh();
			}

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

				// 销毁已创建的单例Bean以避免悬挂资源
				destroyBeans();

				// 重置'active'标志
				cancelRefresh(ex);

				// 将异常传播给调用者
				throw ex;
			}

			finally {
				// 重置Spring核心中的常见内省缓存,因为我们可能不再需要单例Bean的元数据...
				resetCommonCaches();
				contextRefresh.end();
			}
		}
	}

总结

这里只是简单描述了Spring启动的流程,后续会对refresh()方法中的各个部分针对性的学习,例如文件扫描、依赖注入、循环依赖问题、事务、AOP等实现.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值