网站Logo GESONG

Spring容器启动过程

gesong
21
2025-05-17

整体流程

1. new一个ApplicationContext实现类(Spring容器/IOC容器/Spring上下文),比如AnnotationConfigApplicationContext(通过配置类启动)、ClassPathXmlApplicationContext(通过xml配置文件启动)

2. 调用BeanFactory后置处理器完成扫描(invokeBeanFactoryPostProcessors),如ConfigurationClassPostProcessor,解析出类信息

3. 将解析出来的类信息封装成BeanDefinition对象,存储到beanDefinitionMap中

4. 做一些其他的事情,比如国际化,注册BeanPostProcessor等

5. 在finishBeanFactoryInitialization -> preInstantiateSingletons 方法中完成实例化单例bean,循环beanDefinitionMap依次创建,创建前会先判断是否是单例,是否是懒加载,是否抽象类等。然后通过调用BeanFactory.getBean(beanName)方法来创建bean。创建bean的过程分为3大步:a. 实例化(纯净bean);b. 属性注入(@AutoWired、@Value、循环依赖:通过三级缓存解决);c. 初始化(xxxAware、初始化方法回调@PostConstruct)。创建好的单例bean放在DefaultSingletonBeanRegistry类中的Map对象singletonObjects中(又叫做单例池)

  • 实例化过程:通过反射的方式推断构造函数,默认调用无参构造函数实例化;另外也可以通过工厂方法来实例化(指定factory-method和factory-bean,对于@bean注解,factory-method就是@bean修饰的方法,factory-bean就是该方法所在的类),实例化后的bean是一个纯净的bean,各种属性都是null

  • 属性注入:注入@AutoWired和@Value注解修饰的属性,在这期间可能会存在循环依赖的问题,Spring通过三级缓存解决该问题

  • 初始化:在该阶段会调用各种XXXAware扩展接口,然后调用初始化方法,在初始化方法前后会调用postProcessBeforeInitialization和postProcessAfterInitialization方法。

源码

以AnnotationConfigApplicationContext为例

构造方法

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
        // 调用无参构造器,
        // 在其中实例化了AnnotatedBeanDefinitionReader(在这个过程中会注册一些Spring内部的PostProcessor,比如用来解析配置类的ConfigurationClassPostProcessor)和ClassPathBeanDefinitionScanner
		this();
        // 将启动类注册到beanDefinitionMap
		register(componentClasses);
		refresh();
	}

refresh方法

	public void refresh() throws BeansException, IllegalStateException {
		this.startupShutdownLock.lock();
		try {
			this.startupShutdownThread = Thread.currentThread();

			StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");

			// 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);

				StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
				// Invoke factory processors registered as beans in the context.
                // 执行bean工厂后置处理器(比如ConfigurationClassPostProcessor,会解析配置类并根据配置扫描包,将扫描到的bean注册到beanDefinitionMap中,另外还会将配置了进行增强,即创建配置类的动态代理类)
				invokeBeanFactoryPostProcessors(beanFactory);
				// Register bean processors that intercept bean creation.
                // 注册bean后置处理器
				registerBeanPostProcessors(beanFactory);
				beanPostProcess.end();

				// 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.
                // 实例化所有的单例bean
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
                // 发布事件ContextRefreshedEvent
				finishRefresh();
			}

			catch (RuntimeException | Error 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 {
				contextRefresh.end();
			}
		}
		finally {
			this.startupShutdownThread = null;
			this.startupShutdownLock.unlock();
		}
	}

finishBeanFactoryInitialization方法

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 BeanFactoryPostProcessor
    // (such as a PropertySourcesPlaceholderConfigurer 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();
}

preInstantiateSingletons方法

@Override
public void preInstantiateSingletons() throws BeansException {
    if (logger.isTraceEnabled()) {
       logger.trace("Pre-instantiating singletons in " + this);
    }

    // Iterate over a copy to allow for init methods which in turn register new bean definitions.
    // While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

    // Trigger initialization of all non-lazy singleton beans...
    for (String beanName : beanNames) {
       RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
       if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
          if (isFactoryBean(beanName)) {
             Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
             if (bean instanceof SmartFactoryBean<?> smartFactoryBean && smartFactoryBean.isEagerInit()) {
                getBean(beanName);
             }
          }
          else {
             // 通过getBean方法从单例池中循环获取,不存在则创建
             getBean(beanName);
          }
       }
    }

    // Trigger post-initialization callback for all applicable beans...
    for (String beanName : beanNames) {
       Object singletonInstance = getSingleton(beanName);
       if (singletonInstance instanceof SmartInitializingSingleton smartSingleton) {
          StartupStep smartInitialize = getApplicationStartup().start("spring.beans.smart-initialize")
                .tag("beanName", beanName);
          smartSingleton.afterSingletonsInstantiated();
          smartInitialize.end();
       }
    }
}

动物装饰