spring源码分析之启动流程

spring源码分析

1、 spring源码中组件介绍:

  

2、spring启动工厂创建和实例化bean的流程:

下图是spring 容器的关系图

 

分析是基于注解的方式,非解析spring.xml的方式

说明:

AnnotationConfigApplicationContext  是ApplicationContext的子类;也是BeanDefinitionRegistry的实现类,即 即时spring的ioc容器,也是bd的注册器;

1、 创建AnnotationConfigApplicationContext  ,参数 AppConfig,调用AnnotationConfigApplicationContext  的构造方法,

  说明:Appconfig是基于注解的方式配置bean,功能和spring.xm相同;需要 @ComponentScan和@Configuration一起使用;假如不使用@Configuration注解,会生成多例bean;使用该注解,当引用bean的时候会从spring的单例工厂取出bean。

2、 AnnotationConfigApplicationContext(Class<?>... annotatedClasses){} 构造方法,主要有一下处理逻辑:

  this();

  register(annotatedClasses);

  refresh();

a、  this()方法

  

  AnnotationConfigApplicationContext的无参构造方法,用来初始化定义读取器和扫描器

  调用父类GenericApplicationContext无参构造函数,初始化一个BeanFactory:DefaultListableBeanFactory

  这里的 AnnotatedBeanDefinitionReader注册了spring自带的5个bean,分别为:

                ConfigurationClassPostProcessor

                AutowiredAnnotationBeanPostProcessor

                CommonAnnotationBeanPostProcessor

                EventListenerMethodProcessor

                DefaultEventListenerFactory

ClassPathBeanDefinitionScanner :一个bean定义扫描器,它检测类路径上的bean候选对象;        

b、 register(annotatedClasses)方法,方法参数可能为多个,

  b.1  循环遍历,注册AppConfig, ApplicationContext传入的配置类

  b.2  方法内部  主要调用BeanDefinitionReaderUtils. registerBeanDefinition()方法,将配置类 转换为对应的 BeanDefination,注册到spring容器中

        

c、  refresh()

  c.1  refresh()方法主要完成bean加载到spring容器的工作(非@Configuratiionbean修饰的配置bean)

  c.2     

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

      // Tell the subclass to refresh the internal bean factory.
      // 获得刷新的beanFactory
      // 对于AnnotationConfigApplicationContext,作用:
      // 1.调用org.springframework.context.support.GenericApplicationContext.refreshBeanFactory,
      // 只是指定了SerializationId
      // 2.直接返回beanFactory(不用创建,容器中已存在)

      //  对于ClassPathXmlApplicationContext,作用:
      // 1.调用AbstractRefreshableApplicationContext.refreshBeanFactory
      // 2.如果存在beanFactory,先销毁单例bean,关闭beanFactory,再创建beanFactory
      // 3.注册传入的spring的xml配置文件中配置的bean,注册到beanFactory
      // 4.将beanFactory赋值给容器,返回beanFactory
      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

      // Prepare the bean factory for use in this context.
      // 准备bean工厂: 指定beanFactory的类加载器, 添加后置处理器,注册缺省环境bean等
      // beanFactory添加了2个后置处理器 ApplicationContextAwareProcessor, ApplicationListenerDetector (new )
      prepareBeanFactory(beanFactory);

      try {
         // Allows post-processing of the bean factory in context subclasses.
         // 空方法
         // 允许在上下文的子类中对beanFactory进行后处理
         // 比如 AbstractRefreshableWebApplicationContext.postProcessBeanFactory
         postProcessBeanFactory(beanFactory);

         // Invoke factory processors registered as beans in the context.
         // 1.通过beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)
         //   拿到ConfigurationClassPostProcessor
         // 2.通过ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry,注册所有注解配置的bean
         // 注册的顺序: @ComponentScan>实现ImportSelector>方法bean>@ImportResource("spring.xml")
         //  > 实现 ImportBeanDefinitionRegistrar  (相对的顺序,都在同一个配置类上配置)
         // 3. 调用ConfigurationClassPostProcessor#postProcessBeanFactory
         //  增强@Configuration修饰的配置类  AppConfig--->AppConfig$$EnhancerBySpringCGLIB
         // (可以处理内部方法bean之间的调用,防止多例)
         //  添加了后置处理器 ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor (new)
         invokeBeanFactoryPostProcessors(beanFactory);

         // Register bean processors that intercept bean creation.
         // 注册拦截bean创建的后置处理器:
         // 1.添加Spring自身的:  BeanPostProcessorChecker (new)  以及注册了beanDefinition的两个
         //  CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor
         //  重新添加ApplicationListenerDetector(new ) ,删除旧的,移到处理器链末尾
         // 2.用户自定义的后置处理器
         // 注册了beanDefinition的会通过 beanFactory.getBean(ppName, BeanPostProcessor.class) 获取后置处理器
         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) {
         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();
      }
   }
}
 Appconfig中不同注解的bean的加载顺序:
  注册的顺序: @ComponentScan > 实现ImportSelector  > 方法bean  >  @ImportResource("spring.xml") > 实现 ImportBeanDefinitionRegistrar  (相对的顺序,都在同一个配置类上配置)
 

猜你喜欢

转载自www.cnblogs.com/wl20200316/p/12505028.html