一、浅析Spring启动流程(源码分析)

403 阅读8分钟

浅析Spring系列

一、浅析Spring启动流程

二、浅析Spring Bean的生命周期

三、浅析Spring循环依赖

四、浅析Spring事件

五、浅析Spring AOP

六、浅析Spring MVC


浅析Spring启动流程(源码分析)

在Spring的启动上,主要以xxxApplicationContext作为启动类,本文将以当前流程的AnnotationConfigApplicationContext为例,浅析一下Spring的启动流程。正常使用Spring启动代码如下:

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(xxx.class); //配置类
//context.scan(""); //扫描路径
context.refresh();

首先AnnotationConfigApplicationContext内部会有AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner两个实例,这两个类的作用为读取Bean的配置。本质上都是讲Bean解析成BeanDefinition,然后注册到IOC容器中(DefaultListableBeanFactory),等待被调用。

在实例化AnnotatedBeanDefinitionReader时,会注册BeanFactoryPostProcessor到IOC容器

  • ConfigurationClassPostProcessor:处理@Configuration注解。

还会注册几个重要的BeanPostProcessor到IOC容器中:

  • AutowiredAnnotationBeanPostProcessor:处理@Value、@Autowired注解。
  • CommonAnnotationBeanPostProcessor:主要处理@PostConstruct、@PreDestroy注解。

启动流程代码如下,主要有几个步骤:

  1. 准备阶段
  2. BeanFactory处理
  3. BeanFactoryPostProcessor处理
  4. BeanPostProcessor处理
  5. 事件处理
  6. 实例化非延迟Bean
  7. 结束启动
//AbstractApplicationContext#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();
      }  finally {
         // Reset common introspection caches in Spring's core, since we
         // might not ever need metadata for singleton beans anymore...
         resetCommonCaches();
      }
   }
}

1.准备阶段

主要是状态记录、数据存储准备

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

   // 模版方法
   initPropertySources();

   // 属性校验
   getEnvironment().validateRequiredProperties();

   // 存储事件监听相关内容
   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<>();
}

2.BeanFactory处理

BeanFactory为Spring的底层IOC容器

2.1获取BeanFactory

AnnotationConfigApplicationContext继承GenericApplicationContext,在默认构造下,GenericApplicationContext会创建一个BeanFactory,new一个DefaultListableBeanFactory实例。

public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}

obtainFreshBeanFactory方法,默认情况下会返回DefaultListableBeanFactory

//AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
   refreshBeanFactory();
   return getBeanFactory();
}
//GenericApplicationContext#getBeanFactory
public final ConfigurableListableBeanFactory getBeanFactory() {
   return this.beanFactory;
}

2.2设置BeanFactory

  1. 设置ClassLoader
  2. 设置expresess解析器
  3. 设置资源类型字段转换,在初始化阶段,将属性转换成所需的类型。
    //AbstractApplicationContext#prepareBeanFactory
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // Tell the internal bean factory to use the context's class loader etc.
        beanFactory.setBeanClassLoader(getClassLoader());
        beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    }

添加ApplicationContextAwareProcessor,该BeanPostProcessor主要处理各种Aware接口回调。

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.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

最后定义了几个环境变量相关的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());
}

2.3处理BeanFactory

实际是个模版方法,有需要的子类实现该方法即可

//AbstractApplicationContext#postProcessBeanFactory
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}

3.BeanFactoryPostProcessor处理

内部实际会通过静态方法调用

//AbstractApplicationContext#invokeBeanFactoryPostProcessors
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
   PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}

内部有两个逻辑

3.1.处理BeanDefinitionRegistryPostProcessor接口

先处理BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口

按照以下顺序处理BeanDefinitionRegistryPostProcessor接口

  • 实现了PriorityOrdered接口
  • 实现了Order接口
  • 其他

处理逻辑为:先进行排序(可能有多个接口实现),然后调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry接口。

等以上BeanDefinitionRegistryPostProcessor逻辑都处理完之后,再调用BeanFactoryPostProcessor的postProcessBeanFactory方法。

3.2.处理BeanFactoryPostProcessor接口

整体上也BeanDefinitionRegistryPostProcessor类似,也是通过以下顺序处理BeanFactoryPostProcessor接口

  • 实现了PriorityOrdered接口
  • 实现了Order接口
  • 其他

处理逻辑为:先进行排序(可能有多个接口实现),然后调用BeanFactoryPostProcessor的postProcessBeanFactory方法。

当然,因为BeanDefinitionRegistryPostProcessor为BeanFactoryPostProcessor的子接口,在实现的时候有去重,不会出现重复调用postProcessBeanFactory方法。

默认情况下:会有2个内置的BeanFactoryPostProcessor接口,就是在AnnotatedBeanDefinitionReader构造器时添加

  • ConfigurationClassPostProcessor
  • EventListenerMethodProcessor

4.BeanPostProcessor处理

BeanPostProcessor处理通过调用静态方法处理,不过从方法名可以看出,这里的逻辑主要是注册BeanPostProcessor到BeanFactory为主。而BeanPostProcessor的逻辑会贯穿到Bean的生命周期中,可以基于此对Bean进行扩展。

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

4.1 BeanPostProcessorChecker

在处理注册逻辑之前,会添加一个BeanPostProcessorChecker到BeanFactory,这个作用是什么呢?

//PostProcessorRegistrationDelegate#registerBeanPostProcessors
public static void registerBeanPostProcessors(
      ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {

   String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

   int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
   beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
}

BeanPostProcessorChecker的作用,主要是防止bean在所有的BeanPostProcessor注册到BeanFactory之前,就进行了实例化。

假设有个BeanPostProcessor 实现类,在内部依赖的其他的Bean,这样就会导致这个Bean在注册到BeanFactory过程中被创建(因为注册到BeanFactory之前,BeanPostProcessor 会先被实例化),这样就出触发BeanPostProcessorChecker逻辑

@Order
public class MyBeanPostProcessor implements BeanPostProcessor {

   @Autowired
   @Qualifier("createStr")
   private String test;


   @PostConstruct
   public void init(){
      System.out.println("MyBeanPostProcessor reference string : " + test);
   }
}

BeanPostProcessorChecker逻辑也很简单,本身就是一个BeanPostProcessor接口,在postProcessAfterInitialization方法上做拦截,如果bean不是BeanPostProcessor或者不是Spring内部类的情况下,此时BeanFatory的BeanPostProcessor数量小于期望数量,那就打日志警告。在进行注册前,已经获取了所有的BeanPostProcessor数量,但此时注册逻辑可能还没走完,所以数量可能出现不一致。通过这种方式进行检测

//BeanPostProcessorChecker#postProcessAfterInitialization
public Object postProcessAfterInitialization(Object bean, String beanName) {
   if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
         this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
      if (logger.isInfoEnabled()) {
         logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
               "] is not eligible for getting processed by all BeanPostProcessors " +
               "(for example: not eligible for auto-proxying)");
      }
   }
   return bean;
}

4.2 注册逻辑

注册逻辑也很简单,通过顺序处理BeanPostProcessor接口,注意,这个过程中BeanPostProcessor会进行实例化和初始化。

  • 实现了PriorityOrdered接口
  • 实现了Order接口
  • 其他

处理逻辑为:向BeanFactory添加BeanPostProcessor接口。

MergedBeanDefinitionPostProcessor接口(BeanPostProcessor的子接口)会最后添加到BeanFactory,最后在添加ApplicationListenerDetector(BeanPostProcessor接口的实现类)实例到BeanFactory中。

BeanFactory添加BeanPostProcessor逻辑:主要是维护在内部的List中

//AbstractBeanFactory#addBeanPostProcessor
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
   Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
   // Remove from old position, if any
   this.beanPostProcessors.remove(beanPostProcessor);
   // Track whether it is instantiation/destruction aware
   if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
      this.hasInstantiationAwareBeanPostProcessors = true;
   }
   if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
      this.hasDestructionAwareBeanPostProcessors = true;
   }
   // Add to end of list
   this.beanPostProcessors.add(beanPostProcessor);
}

5.事件处理

5.1ApplicationEventMulticaster创建

如果没有这个类的话,就会创建默认的SimpleApplicationEventMulticaster用于事件发布等逻辑。Spring事件相关的处理,在ApplicationContext有统一的入口,但内部处理逻辑都是ApplicationEventMulticaster在处理。

//AbstractApplicationContext#initApplicationEventMulticaster
protected void initApplicationEventMulticaster() {
    this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
    beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}

5.2ApplicationListener注册

  1. 获取ApplicationListener,然后添加到ApplicationEventMulticaster中。
  2. 如果有早期的事件,那么也将通过ApplicationEventMulticaster进行发布。那么为什么会有早期事件?
//AbstractApplicationContext#registerListeners
protected void registerListeners() {
   // Register statically specified listeners first.
   for (ApplicationListener<?> listener : getApplicationListeners()) {
      getApplicationEventMulticaster().addApplicationListener(listener);
   }

   // Do not initialize FactoryBeans here: We need to leave all regular beans
   // uninitialized to let post-processors apply to them!
   String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
   for (String listenerBeanName : listenerBeanNames) {
      getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
   }

   // Publish early application events now that we finally have a multicaster...
   Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
   this.earlyApplicationEvents = null;
   if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
      for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
         getApplicationEventMulticaster().multicastEvent(earlyEvent);
      }
   }
}

为什么会有早期事件?从事件发布来说,其实一般都会使用到ApplicationContext的实现类进行处理,一般来说,会处理到AbstractApplicationContext的publishEvent方法上。而实际上在ApplicationEventMulticaster还没被处理之前,就可有可能会进行事件发布,但此时ApplicationEventMulticaster还没有被处理,可能先记录下来,等ApplicationEventMulticaster添加后再进行处理。

这里会判断earlyApplicationEvents 是否为null,在prepareRefresh方法时会设置为为List;在registerListeners时又会设置为null。

//AbstractApplicationContext#publishEvent
protected void publishEvent(Object event, @Nullable ResolvableType eventType) {
   
   // Decorate event as an ApplicationEvent if necessary
   ApplicationEvent applicationEvent;
   if (event instanceof ApplicationEvent) {
      applicationEvent = (ApplicationEvent) event;
   }
   else {
      applicationEvent = new PayloadApplicationEvent<>(this, event);
      if (eventType == null) {
         eventType = ((PayloadApplicationEvent<?>) applicationEvent).getResolvableType();
      }
   }

   // Multicast right now if possible - or lazily once the multicaster is initialized
   if (this.earlyApplicationEvents != null) {
      this.earlyApplicationEvents.add(applicationEvent);
   }
   else {
      getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType);
   }

   // Publish event via parent context as well...
   if (this.parent != null) {
      if (this.parent instanceof AbstractApplicationContext) {
         ((AbstractApplicationContext) this.parent).publishEvent(event, eventType);
      }
      else {
         this.parent.publishEvent(event);
      }
   }
}

6.实例化非延迟Bean

此步骤的逻辑在AbstractApplicationContext的finishBeanFactoryInitialization方法中,调用BeanFactory的preInstantiateSingletons方法,对非延迟Bean进行实例化

//AbstractApplicationContext#finishBeanFactoryInitialization
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
   beanFactory.preInstantiateSingletons();
}

实例化有几个逻辑:

  1. 找需要实例化的bean:非抽象、单例、不用延迟实例化
  2. 对于FactoryBean来说(通过FactoryBean接口包装了Bean的实例化,可以用于复杂Bean的创建),会判断是否是SmartFactoryBean接口,并且isEagerInit方法为true(默认为false),则会对实际的Bean进行实例化。
  3. 对于实现了SmartInitializingSingleton接口的Bean来说,还会调用afterSingletonsInstantiated方法
//DefaultListableBeanFactory#preInstantiateSingletons
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 FactoryBean) {
               FactoryBean<?> factory = (FactoryBean<?>) bean;
               boolean isEagerInit;
               if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                  isEagerInit = AccessController.doPrivileged(
                        (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
                        getAccessControlContext());
               }
               else {
                  isEagerInit = (factory instanceof SmartFactoryBean &&
                        ((SmartFactoryBean<?>) factory).isEagerInit());
               }
               if (isEagerInit) {
                  getBean(beanName);
               }
            }
         }
         else {
            getBean(beanName);
         }
      }
   }

   // Trigger post-initialization callback for all applicable beans...
   for (String beanName : beanNames) {
      Object singletonInstance = getSingleton(beanName);
      if (singletonInstance instanceof SmartInitializingSingleton) {
         SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
         if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
               smartSingleton.afterSingletonsInstantiated();
               return null;
            }, getAccessControlContext());
         }
         else {
            smartSingleton.afterSingletonsInstantiated();
         }
      }
   }
}

7.结束启动

  1. 会清空资源缓存。
  2. 初始化LifecycleProcessor处理器
  3. LifecycleProcessor启动。会对SmartLifecycle中要求isAutoStartup方法的Lifecycle接口进行调用,start接口。(作用:Lifecycle接口用于实现bean的生命周期)
  4. 发布ContextRefreshedEvent事件

代码如下

//AbstractApplicationContext#finishRefresh
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);
}

无论启动成功还是失败,最后都会调用resetCommonCaches进行清理过程中产生的缓存数据。

//AbstractApplicationContext#resetCommonCaches
protected void resetCommonCaches() {
   ReflectionUtils.clearCache();
   AnnotationUtils.clearCache();
   ResolvableType.clearCache();
   CachedIntrospectionResults.clearClassLoader(getClassLoader());
}