spring boot 源码分析-------ApplicationContext

犀渠玉剑良家子,白马金羁侠少年。这篇文章主要讲述spring boot 源码分析-------ApplicationContext相关的知识,希望能为你提供帮助。
上下文ConfigurableApplicationContext的创建。

context = createApplicationContext();

1protected ConfigurableApplicationContext createApplicationContext() { 2Class< ?> contextClass = this.applicationContextClass; 3if (contextClass == null) { 4try { 5contextClass = Class.forName(this.webEnvironment 6? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); 7} 8catch (ClassNotFoundException ex) { 9throw new IllegalStateException( 10"Unable create a default ApplicationContext, " 11+ "please specify an ApplicationContextClass", 12ex); 13} 14} 15return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); 16}

根据webEnvironment创建对应的上下文。web应用创建的是下面这个类型的上下文。
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";

看AnnotationConfigEmbeddedWebApplicationContext的构造方法。
1public AnnotationConfigEmbeddedWebApplicationContext() { 2this.reader = new AnnotatedBeanDefinitionReader(this); 3this.scanner = new ClassPathBeanDefinitionScanner(this); 4}

需要创建一个reader和一个scanner。
从上面的代码可以看出两个构造方法的参数都是上下文。这里看下这个上下文类的继承实现关系。看出上下文是包含BeanDefinitionRegistry的功能。
【spring boot 源码分析-------ApplicationContext】
spring boot 源码分析-------ApplicationContext

文章图片

 
AnnotatedBeanDefinitionReader用于操作BeanDefinition。
ClassPathBeanDefinitionScanner用于扫描路径下的文件,利用classLoader加载类然后生成BeanDefinition。
看下AnnotatedBeanDefinitionReader,主要包含的BeanDefinitionRegistry实际操作BeanDefinition的、ConditionEvaluator用于完成条件注解的解析和判断(也就是处理注解的)。
1public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { 2Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); 3Assert.notNull(environment, "Environment must not be null"); 4this.registry = registry; 5this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); 6AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 7}

  看下ClassPathBeanDefinitionScanner。
1private final BeanDefinitionRegistry registry; 2 3private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults(); 4 5private String[] autowireCandidatePatterns; 6 7private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator(); 8 9private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

主要包换的也就是BeanDefinitionRegistry、autowireCandidatePatterns、beanNameGenerator、scopeMetadataResolver都是为了解析类转换成BeanDefinition服务的。
创建过后的context包含如下内容:
spring boot 源码分析-------ApplicationContext

文章图片

可以看到beanFactory已经被创建。
spring boot 源码分析-------ApplicationContext

文章图片

里面的beanDefinationMap只包换初始META-INFO里面的六个类。
context实现了BeanDefinition的接口,但是并没有持有BeanDefinitionMap,是DefaultListableBeanFactory里面持有的,也就是实际操作的是DefaultListableBeanFactory里面的BeanDefinition。DefaultListableBeanFactory是GenericApplicationContext持有的。
看GenericApplicationContext也可以发现,对于BeanDefinition实际的操作都在DefaultListableBeanFactory里,GenericApplicationContext对DefaultListableBeanFactory做了代理。

    推荐阅读