spring启动流程 (1) 流程概览

这篇具有很好参考价值的文章主要介绍了spring启动流程 (1) 流程概览。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

本文将通过阅读AnnotationConfigApplicationContext源码,分析Spring启动流程。

创建AnnotationConfigApplicationContext

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(XxConfig.class);
applicationContext.register(YyConfig.class);
applicationContext.refresh();

XxService xxService = applicationContext.getBean(XxService.class);

核心的启动逻辑都在refresh方法中。

构造方法

public AnnotationConfigApplicationContext() {
	this.reader = new AnnotatedBeanDefinitionReader(this);
	this.scanner = new ClassPathBeanDefinitionScanner(this);
}

AnnotatedBeanDefinitionReader类

定义了多个register方法,用于向Spring容器注册BeanDefinition。

在创建AnnotatedBeanDefinitionReader时,会向容器注册几个注解驱动处理器:

  • org.springframework.context.annotation.internalConfigurationAnnotationProcessor: ConfigurationClassPostProcessor
    • BeanFactoryPostProcessor实现,用于解析@Configuration类。
    • 按优先级排序,因为在@Configuration类中声明的任何@Bean方法都必须在任何其他BeanFactoryPostProcessor执行之前注册其对应的BeanDefinition。
  • org.springframework.context.annotation.internalAutowiredAnnotationProcessor: AutowiredAnnotationBeanPostProcessor
    • BeanPostProcessor实现类。
    • @Autowired支持处理器。
  • org.springframework.context.annotation.internalCommonAnnotationProcessor: CommonAnnotationBeanPostProcessor
    • BeanPostProcessor实现类。
    • 支持Resource、PostConstruct、PreDestroy等注解。
  • org.springframework.context.event.internalEventListenerProcessor: EventListenerMethodProcessor
  • org.springframework.context.event.internalEventListenerFactory: DefaultEventListenerFactory

ClassPathBeanDefinitionScanner类

BeanDefinition扫描器,在类路径上检测Bean,并将其注册到Spring容器中。扫描的类是通过类型过滤器检测到的。

refresh方法

public void refresh() throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			initMessageSource();

			// Initialize event multicaster for this context.
			initApplicationEventMulticaster();

			// Initialize other special beans in specific context subclasses.
			onRefresh();

			// Check for listener beans and register them.
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			finishRefresh();
		} catch (BeansException 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();
		}
	}
}

prepareRefresh方法

Prepare this context for refreshing, setting its startup date and active flag as well as performing any initialization of property sources.

protected void prepareRefresh() {
	// Switch to active.
	this.startupDate = System.currentTimeMillis();
	this.closed.set(false);
	this.active.set(true);

	// Initialize any placeholder property sources in the context environment.
	// Replace any stub property sources with actual instances.
	// web相关的ApplicationContext有实现
	initPropertySources();

	// Validate that all properties marked as required are resolvable:
	// see ConfigurablePropertyResolver#setRequiredProperties
	getEnvironment().validateRequiredProperties();

	// Store pre-refresh ApplicationListeners...
	if (this.earlyApplicationListeners == null) {
		this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
	} else {
		// Reset local application listeners to pre-refresh state.
		this.applicationListeners.clear();
		this.applicationListeners.addAll(this.earlyApplicationListeners);
	}

	// Allow for the collection of early ApplicationEvents,
	// to be published once the multicaster is available...
	this.earlyApplicationEvents = new LinkedHashSet<>();
}

obtainFreshBeanFactory方法

Tell the subclass to refresh the internal bean factory.

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
	refreshBeanFactory();
	return getBeanFactory();
}

由于AnnotationConfigApplicationContext继承了GenericApplicationContext类,所以此处获取到的是DefaultListableBeanFactory对象。

prepareBeanFactory方法

配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	// Tell the internal bean factory to use the context's class loader etc.
	beanFactory.setBeanClassLoader(getClassLoader());

	// Standard implementation of the BeanExpressionResolver interface,
	// parsing and evaluating Spring EL using Spring's expression module.
	beanFactory.setBeanExpressionResolver(
        new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
	beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

	// Configure the bean factory with context callbacks.
	// 支持EnvironmentAware, MessageSourceAware, ApplicationContextAware等
	beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
	beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
	beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
	beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
	beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
	beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

	// BeanFactory interface not registered as resolvable type in a plain factory.
	// MessageSource registered (and found for autowiring) as a bean.
	beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
	beanFactory.registerResolvableDependency(ResourceLoader.class, this);
	beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
	beanFactory.registerResolvableDependency(ApplicationContext.class, this);

	// ApplicationListenerDetector处理器自动将ApplicationListener类型Bean添加容器
	beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

	// Detect a LoadTimeWeaver and prepare for weaving, if found.
	if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		// Set a temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}

	// 注册env bean
	if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
		beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
		beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
	}
	if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
		beanFactory
            .registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
	}
}

postProcessBeanFactory方法

Modify the application context's internal bean factory after its standard initialization. All bean definitions will have been loaded, but no beans will have been instantiated yet. This allows for registering special BeanPostProcessors etc in certain ApplicationContext implementations.

在标准初始化之后修改ApplicationContext的内部bean工厂。所有的BeanDefinition都将被加载,但还没有任何Bean被实例化。这允许在某些ApplicationContext实现中注册特殊的BeanPostProcessors等。

invokeBeanFactoryPostProcessors方法

实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// 调用BeanFactoryPostProcessors
	PostProcessorRegistrationDelegate
        .invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

调用BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。

registerBeanPostProcessors方法

实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

把BeanPostProcessor实例添加到beanPostProcessors中:

  1. 从容器获取所有的BeanPostProcessor Bean
  2. 按照以下顺序注册:实现了PriorityOrdered接口、实现了Ordered接口、普通BeanPostProcessor、实现MergedBeanDefinitionPostProcessor接口
private static void registerBeanPostProcessors(
		ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {

	for (BeanPostProcessor postProcessor : postProcessors) {
		beanFactory.addBeanPostProcessor(postProcessor);
	}
}

initMessageSource方法

国际化。

protected void initMessageSource() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
		this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
		// Make MessageSource aware of parent MessageSource.
		if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
			HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
			if (hms.getParentMessageSource() == null) {
				// Only set parent context as parent MessageSource if no parent MessageSource
				// registered already.
				hms.setParentMessageSource(getInternalParentMessageSource());
			}
		}
	} else {
		// Use empty MessageSource to be able to accept getMessage calls.
		DelegatingMessageSource dms = new DelegatingMessageSource();
		dms.setParentMessageSource(getInternalParentMessageSource());
		this.messageSource = dms;
		beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
	}
}

initApplicationEventMulticaster方法

初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster。

protected void initApplicationEventMulticaster() {
	ConfigurableListableBeanFactory beanFactory = getBeanFactory();
	if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
		this.applicationEventMulticaster = beanFactory.getBean(
            APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
	} else {
		this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
		beanFactory.registerSingleton(
            APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
	}
}

onRefresh方法

可以重写的模板方法,以添加指定的刷新逻辑。在初始化特殊Bean时调用,在实例化单例之前调用。

默认什么都不做。

SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer。

registerListeners方法

添加实现ApplicationListener的Bean作为侦听器。不会影响其他侦听器,这些侦听器可以在不使用Bean的情况下添加。

finishBeanFactoryInitialization方法

完成Bean工厂的初始化,初始化所有剩余的单例Bean。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
	// Initialize conversion service for this context.
	if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
			beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
		beanFactory.setConversionService(
				beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
	}

	// Register a default embedded value resolver if no bean post-processor
	// (such as a PropertyPlaceholderConfigurer bean) registered any before:
	// at this point, primarily for resolution in annotation attribute values.
	if (!beanFactory.hasEmbeddedValueResolver()) {
		beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
	}

	// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
	String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
	for (String weaverAwareName : weaverAwareNames) {
		getBean(weaverAwareName);
	}

	// Stop using the temporary ClassLoader for type matching.
	beanFactory.setTempClassLoader(null);

	// Allow for caching all bean definition metadata, not expecting further changes.
	beanFactory.freezeConfiguration();

	// Instantiate all remaining (non-lazy-init) singletons.
	beanFactory.preInstantiateSingletons();
}

finishRefresh方法

完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件。文章来源地址https://www.toymoban.com/news/detail-500951.html

protected void finishRefresh() {
	// Clear context-level resource caches (such as ASM metadata from scanning).
	clearResourceCaches();

	// Initialize lifecycle processor for this context.
	initLifecycleProcessor();

	// Propagate refresh to lifecycle processor first.
	getLifecycleProcessor().onRefresh();

	// Publish the final event.
	publishEvent(new ContextRefreshedEvent(this));

	// Participate in LiveBeansView MBean, if active.
	LiveBeansView.registerApplicationContext(this);
}

启动流程

  1. 创建AnnotationConfigApplicationContext对象
    • 创建AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner
    • 向容器注册几个注解驱动处理器:ConfigurationClassPostProcessor, AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor等
  2. 调用applicationContext.register(XxConfig.class)注册配置类
  3. 调用refresh()方法:
    • prepareRefresh方法准备工作:初始化PropertySources、validateRequiredProperties等
    • Refresh the internal beanFactory
    • 配置BeanFactory的标准上下文,例如上下文的ClassLoader和后置处理器
    • 实例化并调用注册的所有BeanFactoryPostProcessor,如果指定顺序则按照顺序调用,必须在单例实例化之前调用
    • 实例化并注册所有BeanPostProcessor,如果指定顺序则按照顺序注册,必须在应用Bean实例化之前调用
    • 初始化MessageSource
    • 初始化ApplicationEventMultimaster,如果Context中未定义,则使用SimpleApplicationEventMultimaster
    • onRefresh方法,SpringBoot中的ServletWebServerApplicationContext实现类在这个阶段创建WebServer
    • 添加实现ApplicationListener的Bean作为侦听器
    • 完成Bean工厂的初始化,初始化所有剩余的单例Bean
    • 完成刷新工作,调用LifecycleProcessor的onRefresh()方法并发布ContextRefreshedEvent事件

到了这里,关于spring启动流程 (1) 流程概览的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • spring启动流程 (2) Bean实例化流程

    本文通过阅读Spring源码,分析Bean实例化流程。 上一篇文章已经介绍,Bean实例化入口在AbstractApplicationContext类的finishBeanFactoryInitialization方法: 返回指定beanName的(原始)单例对象,如果没有则创建一个新对象: 创建Bean实例、填充属性、调用后置处理器等:

    2024年02月11日
    浏览(81)
  • Spring Boot 启动流程

    加载配置 Spring Boot在启动时会加载应用程序的配置文件(例如application.properties或application.yml),并将其转化为内部的配置对象。 创建应用程序上下文 Spring Boot会创建一个应用程序上下文(ApplicationContext),它是Spring框架的核心容器。应用程序上下文负责管理Bean的生命周期和

    2024年02月06日
    浏览(50)
  • Spring Boot启动流程简析

    文章首发地址 可以穿件独立的Spring应用程序,可以创建可执行的jars 内嵌tomcat或jetty等Servlet容器 提供“入门”依赖项,以简化构建配置。尽可能自动配置Spring和第三方库 提供可用于生产的功能,例如指标、运行状况检查和外部化配置 了解基本的启动注解 AnnotationUtil.java,该

    2024年02月16日
    浏览(57)
  • Spring Boot的启动流程

    Spring Boot是作为Spring的脚手架框架,其本身并不提供Spring的核心功能,而是来达到快速构建项目、预置三方配置、开箱即用的目的 。 从本质上来说,Spring Boot就是Spring,它做了那些没有它你自己也会去做的Spring Bean配置。 Spring Boot使用“习惯优于配置”的理念让你的项目快速

    2024年02月02日
    浏览(38)
  • spring启动流程 (4) FactoryBean详解

    实现类对象将被用作创建Bean实例的工厂,即调用getObject()方法返回的对象才是真正要使用的Bean实例,而不是直接将FactoryBean对象作为暴露的Bean实例。 FactoryBeans可以支持singleton和prototype,并且可以根据需要懒加载或在启动时立即创建对象。 这个接口在编写扫描接口生成代理对

    2024年02月13日
    浏览(34)
  • spring启动流程 (3) BeanDefinition详解

    BeanDefinition在Spring初始化阶段保存Bean的元数据信息,包括Class名称、Scope、构造方法参数、属性值等信息,本文将介绍一下BeanDefinition接口、重要的实现类,以及在Spring中的使用示例。 用于描述了一个Bean实例,该Bean实例具有属性、构造方法参数以及由具体实现提供的其他信息

    2024年02月12日
    浏览(42)
  • spring启动流程 (5) Autowired原理

    BeanClass可以在构造方法上标注@Autowired注解,Spring在创建Bean实例时将自动为其注入依赖参数 Spring会优先使用标注@Autowired注解的构造方法 当一个构造方法标注了@Autowired注解且required=true时,其余构造方法不允许再标注@Autowired注解 当多个构造方法标注了@Autowired注解且required=fa

    2024年02月16日
    浏览(42)
  • 【JAVA面试】Spring容器的启动流程

    提示:文章先作为初版,等后续时间充足后,补充更深的内容 当启动Spring容器时,会按照以下步骤进行: 扫描并注册Bean定义 :Spring容器会扫描指定的包或目录,查找带有 特定注解(如@Component、@Service、@Repository等)的类。它会创建对应的BeanDefinition对象 ,包含了Bean的元数

    2024年02月03日
    浏览(35)
  • 三分钟了解Spring Boot 的启动流程

    👏作者简介:大家好,我是冰点,从业11年,目前在物流独角兽企业从事技术方面工作, 🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人 📝联系方式:iceicepip,加我进群,大家一起学习,一起进步👀 背景:最近有位开发同学说面试被问到Spring Boot 的启动

    2024年02月08日
    浏览(46)
  • 全网最清楚的:Spring Boot 启动流程讲解

    Spring Boot 启动流程 简介 步骤 加载配置 创建应用程序上下文 执行自动配置 启动应用程序 处理请求 源码层说明 扩展 自定义注解以及自定义注解实现中有bean,与启动流程什么有关 Bean扫描 注解处理 Spring Boot 的启动流程 充分利用了 Spring 框架的强大功能,同时又为开发者提供

    2024年02月07日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包