Spring源码之AbstractApplicationContext

说明: AbstractApplicationContext是Spring上下文非常关键的一个类,Spring的上下文基本上都是基于继承该类实现扩展的,所以掌握该抽象类是非常重要的。文章写的很杂乱,想到什么就写上了什么,写的不好还请多多包涵。能力和文笔实力有限,仅作抛砖引玉之用。

一、类图介绍

图一:

AbstractApplicationContext.png

1. AbstractApplicationContext 抽象应用上下文,是所有Spring应用上下文的基类。

2. DisposableBean 可销毁的bean, bean生命周期结束前调用destory方法。亦可以使用destory-method。

3. DefaultResourceLoader  默认的资源加载器。ClassPathResource和UrlResource和ClassPathContextResource三种

4. ConfigurableApplicationContext 可配置化的上下文

5. LifeCycle  生命周期对象

6. ListableBeanFactory 具有列表能力的bean工厂

7. HierararchicalBeanFactory 具有层级关系能力bean工厂

8. ApplicationEventPublisher 可以发布事件的类

9. ResourcePatternResolver 资源模式处理器(根据路径获取解析出对应的资源)

10. MessageSource 国际化信息


从图一可以看出一个Spring应用上下文具备的能力:

  1. BeanFactory bean工厂的能力

  2. ResourceLoader 资源加载的能力

  3. Lifecycle 生命周期的能力

  4. MessageSource 国际化的能力

  5. DisposableBean 销毁bean的能力

二、类成员变量介绍


public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";

protected final Log logger; // 日志

private String id; // 实例化ID

private ApplicationContext parent; // 父上下文

private final List beanFactoryPostProcessors; // Bean工厂的后置处理器

private String displayName; // 别名

private long startupDate; // 启动时间

private boolean active; // 是否活跃

private final Object activeMonitor; // 活跃监听器(锁)

private final Object startupShutdownMonitor; 启动关闭监听器(锁)

private Thread shutdownHook; // 关闭Hook

private ResourcePatternResolver resourcePatternResolver; // 资源模式解析器

private MessageSource messageSource; // 国际化信息

private ApplicationEventMulticaster applicationEventMulticaster; // 事件广播器

private List applicationListeners; // 应用监听器

三、启动refresh方法


public void refresh() throws BeansException, IllegalStateException {

    Object var1 = this.startupShutdownMonitor; // 启动关闭监听器(锁)

    synchronized(this.startupShutdownMonitor) {

        this.prepareRefresh(); // 准备刷新

        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();  // 获取刷新过的bean工厂

        this.prepareBeanFactory(beanFactory); // 注册可能的BeanPostProcessors

        try {

            this.postProcessBeanFactory(beanFactory); //  修改上下文内部bean工厂当他被初始化之后

            this.invokeBeanFactoryPostProcessors(beanFactory); // 调用执行beanFactory后置处理器

            this.registerBeanPostProcessors(beanFactory); // 注册Bean后置处理器

            this.initMessageSource(); // 初始化国际化处理器

            this.initApplicationEventMulticaster(); // 初始化应用事件广播器

            this.onRefresh(); // 刷新 交给子类去处理

            this.registerListeners(); // 注册监听器

            this.finishBeanFactoryInitialization(beanFactory); // 完成bean工厂初始化 (非延迟加载的实现)

            this.finishRefresh(); // 完成刷新(发布对应的事件 上下文启动完成)

        } catch (BeansException var5) {

            beanFactory.destroySingletons();  // 销魂所有的单例bean

            this.cancelRefresh(var5); // 取消刷新

            throw var5; // 抛出异常

        }

    }

}

四、继承AbstrctGenericApplicationContext的两个核心基类: GenericApplicationContext 和 AbstractRefreshableApplicationContext,其余上下文基本上都是基于继承这两个其中之一进行扩展的。

GenericApplicationContext 泛型上下文(Springboot 采用的这个)
特点: 灵活
参考: https://www.jianshu.com/p/524d62ee91fb

GenericApplicationContext ctx = new GenericApplicationContext();
//使用XmlBeanDefinitionReader
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
//加载ClassPathResource
xmlReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
PropertiesBeanDefinitionReader propReader = new PropertiesBeanDefinitionReader(ctx);
propReader.loadBeanDefinitions(new ClassPathResource("otherBeans.properties"));
//调用Refresh方法
ctx.refresh();

//和其他ApplicationContext方法一样的使用方式
MyBean myBean = (MyBean) ctx.getBean("myBean");

AbstractRefreshableApplicationContext (SpringMvc用的这个)
例如Springmvc(XmlWebApplicationContext)

loadBeanDefinitions方法
XmlBeanDefinitionReader(beanFactory).loadBeanDefinitions(configLocation) 
==> doLoadBeanDefinitions(InputSource inputSource, Resource resource)
==>  BeanDefinitionDocumentReader.registerBeanDefinitions(Document var1, XmlReaderContext var2)
==> {
  ...
  this.preProcessXml(root);
  this.parseBeanDefinitions(root, this.delegate);
  this.postProcessXml(root);
}

五. ClassPathBeanDefinitionScanner 介绍

@ComponentScan和<context:component-scan/>最终使用的包扫描都是该类,也体现spring代码的复用性很强。
<context:component-scan/>的代码流程

<context:component-scan/>对应
ContextNamespaceHandler.ComponentScanBeanDefinitionParser
==> ClassPathBeanDefinitionScanner.scan(basePackages)

@ComponentScan流程,核心在于ConfigurationClassPostProcessor(处理@Configuration)这个BeanFactory后置处理器
Springmvc和Springboot注册ConfigurationClassPostProcessor方式不同,
先看Springmvc,Springmvc入口还是<context:component-scan/>,
下面看调用链

ContextNamespaceHandler.ComponentScanBeanDefinitionParser
==> ClassPathBeanDefinitionScanner.scan(basePackages)
==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);(重点核心)
==> registerPostProcessor(new RootBeanDefinition(ConfigurationClassPostProcessor.class))

Springboot 的入口则是AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory)
下面看调用链

AnnotationConfigServletWebServerApplicationContext(DefaultListableBeanFactory beanFactory)
==> new AnnotatedBeanDefinitionReader(this)
// 和SpringMvc一样都会到这一步
==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)
==> registerPostProcessor(new RootBeanDefinition(ConfigurationClassPostProcessor.class))

上面重要的两个方法
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)(处理很多注解@Autowire @Resoure等等)和 ConfigurationClassPostProcessor.class
先只看ConfigurationClassPostProcessor,这个类使用是用于处理类上有@Configuration注解

ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
==>  processConfigBeanDefinitions(registry)
==> ConfigurationClassParser.parse(candidates)
==> processConfigurationClass(ConfigurationClass configClass)
==> @Conditional == >if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) return 
==> doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
 {
     @Component ==> processMemberClasses(configClass, sourceClass);
     @PropertySource ==> processPropertySource(AnnotationAttributes propertySource);
     @ComponentScan ==> ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) ==> ClassPathBeanDefinitionScanner.doScan(String... basePackages)
     @Import ==> processImports(configClass, sourceClass, getImports(sourceClass), true);
     @ImportResource ==> ConfigurationClass.addImportedResource(resolvedResource, readerClass);
     @Bean ==> ConfigurationClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
    Register default methods on interfaces implemented by the configuration class ==> processInterfaces
 }

// 对于ComponentScanAnnotationParser.class
ComponentScanAnnotationParser.parse()
==> ClassPathBeanDefinitionScanner.scan()

可以看到最终@ComponentScan交给ClassPathBeanDefinitionScanner去处理进行包扫描,spring代码的复用性是很强的,这也是值得去学习的地方。

六. aware的实现

包括ApplicationContextAware ResourceLoaderAware ApplicationEventPublisherAware MessageSourceAware BeanFactoryAware,
主要交给ApplicationContextAwareProcessor 这个Bean后置处理器。
看代码

postProcessBeforeInitialization(Object bean, String beanName)
==> invokeAwareInterfaces {
    if (bean instanceof Aware) {
            if (bean instanceof EnvironmentAware) {
                ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
            }
            if (bean instanceof EmbeddedValueResolverAware) {
                ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
            }
            if (bean instanceof ResourceLoaderAware) {
                ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
            }
            if (bean instanceof ApplicationEventPublisherAware) {
                ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
            }
            if (bean instanceof MessageSourceAware) {
                ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
            }
            if (bean instanceof ApplicationContextAware) {
                ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
            }
        }
}

那么问题来了,ApplicationContextAwareProcessor是在那一步注入的呢,可以很轻松找到在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()));

        // Configure the bean factory with context callbacks.
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
        beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
        beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
        ...
}

由于AbstractApplicationContext是基类,Springmvc和Springboot是一样的方式。

七.各个注解的实现原理(主要就是上面的AnnotationConfigUtils)

核心类ClassPathBeanDefinitionScanner.scan(String... basePackages)

/**
* Perform a scan within the specified base packages.
* @param basePackages the packages to check for annotated classes
* @return number of beans registered
*/
public int scan(String... basePackages) {
  int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
 // 扫描注入@component的派生注解
  doScan(basePackages);
  // Register annotation config processors, if necessary.
  if (this.includeAnnotationConfig) {
      AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  }

  return this.registry.getBeanDefinitionCount() - beanCountAtScanStart;

}

@component的派生性
@Repository @Controller @Service @Repository @Configuration的支持如下方法
ClassPathBeanDefinitionScanner.doScan(String... basePackages) 
==>  findCandidateComponents(String basePackage)
==>  scanCandidateComponents(basePackage)
==> isCandidateComponent 为true则添加。主要是Component的派生注解都为true

可能要问为什么, 那么答案在ClassPathScanningCandidateComponentProvider中
ClassPathScanningCandidateComponentProvider.registerDefaultFilters()
==> this.includeFilters.add(new AnnotationTypeFilter(Component.class));
==> {
    // 见AnnotationTypeFilter的match方法
    AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
   return metadata.hasAnnotation(this.annotationType.getName()) ||
                (this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
}

// isCandidateComponent 方法
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
        for (TypeFilter tf : this.excludeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return false;
            }
        }
        for (TypeFilter tf : this.includeFilters) {
            if (tf.match(metadataReader, this.metadataReaderFactory)) {
                return true;
            }
        }
        return false;
    }
}
@其他相关注解

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {

        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
        // 向容器中增加@Configuration相关的处理器ConfigurationClassPostProcessor
        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));
        }
        //增加@Autowired、@Value、@Inject相关的处理器AutowiredAnnotationBeanPostProcessor
        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));
        }
//在支持JSR-250条件下注册javax.annotation包下注解处理器,包括@PostConstruct、@PreDestroy、@Resource注解等
        // 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));
        }
//支持jpa的条件下,注册org.springframework.orm.jpa.support.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));
        }
// 增加@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));
        }
// 注册支持@EventListener注解的处理器, 也就是DefaultEventListenerFactory实例了
        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;
    }

@Configuration 注解

ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry 和 postProcessBeanFactory


postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)==> processConfigBeanDefinitions(registry) ==>

ConfigurationClassParser.parse(candidates) ==>

processConfigurationClass(ConfigurationClass configClass)

==> @Conditional == >if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) return

==> doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)

{

    @Component ==> processMemberClasses(configClass, sourceClass);

    @PropertySource ==> processPropertySource(AnnotationAttributes propertySource);

    @ComponentScan ==> ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) ==> ClassPathBeanDefinitionScanner.doScan(String... basePackages)

    @Import ==> processImports(configClass, sourceClass, getImports(sourceClass), true);

    @ImportResource ==> ConfigurationClass.addImportedResource(resolvedResource, readerClass);

    @Bean ==> ConfigurationClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));

    Register default methods on interfaces implemented by the configuration class ==> processInterfaces

}

==> add(ImportAwareBeanPostProcessor)

八 Springmvc 包扫描加载流程总结(XmlWebApplicationContext )


XmlWebApplicationContext ==> {

    getConfigLocation(String location) 默认"/WEB-INF/applicationContext.xml"

    loadBeanDefinitions 加载xml ==> 不同的节点对应不同的NamespaceHandler处理

    {

      <context:component-scan> ==> ContextNamespaceHandler

          ==> ComponentScanBeanDefinitionParser.parse

          ==> ClassPathBeanDefinitionScanner.scan(String[] basePackages)

          ==> {

              ==> doScan(basePackages) 扫描@Component派生注解 (@Component @Repository                          @Controller @Service @Repository @Configuration)并注入IOC容器

              ==> AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry) 扫描

              {

                  ==> 1.向容器中增加@Configuration相关的处理器ConfigurationClassPostProcessor

                  ==> 2.增加@Autowired、@Value、@Inject相关的处理器     AutowiredAnnotationBeanPostProcessor

                  ==> 3.在支持JSR-250条件下注册javax.annotation包下注解处理器,包括                                      @PostConstruct、@PreDestroy、@Resource注解等

                  ==> 4.支持jpa的条件下,注册                                                      org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor

                      处理器,处理jpa相关注解

                  ==> 5.增加@EventListener相关处理器

                  ==> 6.注册支持@EventListener注解的处理器, 也就是DefaultEventListenerFactory实例

              }

          }

      }

    }     

}

Springboot 包扫描过程(web)

// 主要分为两部 
//1.将启动类注册为bean
//2.根据已注册bean(启动类)注解展开进行扩展。

SpringApplication.run(Class<?> primarySource, String... args)
==> createApplicationContext()(web是AnnotationConfigServletWebServerApplicationContext,ConfigurationClassPostProcessor.class, 见上面AnnotationConfigServletWebServerApplicationContext分析)
// 
==> prepareContext
==> load(Object source) 
// 将启动类注入到bean中 第一步已完成
==> this.annotatedReader.register(source); 
// 下面是第2步
==> refreshContext()
==> AbstractApplicationContext.refresh()
==> ConfigurationClassPostProcessor(上面已分析)

ConfigurationClassPostProcessor会处理第一步得到的bean,由于@SpringApplication包含@ComponentScan,而当ComponentScan的value为null是默认会扫描当前包下的所有包(分析见ComponentScanAnnotationParser)
ComponentScanAnnotationParser.parse(AnnotationAttributes componentScan, final String declaringClass) {
   ...
   if (basePackages.isEmpty()) {
    basePackages.add(ClassUtils.getPackageName(declaringClass));
   }
   return scanner.doScan(StringUtils.toStringArray(basePackages));
}

ps:写的都是自己的见解,能力有限,难免会有错误,仅做笔记以及抛砖引玉之用。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。