spring boot 源码分析-------ApplicationContext
Posted Over_Watch
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot 源码分析-------ApplicationContext相关的知识,希望对你有一定的参考价值。
上下文ConfigurableApplicationContext的创建。
context = createApplicationContext();
1 protected ConfigurableApplicationContext createApplicationContext() { 2 Class<?> contextClass = this.applicationContextClass; 3 if (contextClass == null) { 4 try { 5 contextClass = Class.forName(this.webEnvironment 6 ? DEFAULT_WEB_CONTEXT_CLASS : DEFAULT_CONTEXT_CLASS); 7 } 8 catch (ClassNotFoundException ex) { 9 throw new IllegalStateException( 10 "Unable create a default ApplicationContext, " 11 + "please specify an ApplicationContextClass", 12 ex); 13 } 14 } 15 return (ConfigurableApplicationContext) BeanUtils.instantiate(contextClass); 16 }
根据webEnvironment创建对应的上下文。web应用创建的是下面这个类型的上下文。
public static final String DEFAULT_WEB_CONTEXT_CLASS = "org.springframework." + "boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext";
看AnnotationConfigEmbeddedWebApplicationContext的构造方法。
1 public AnnotationConfigEmbeddedWebApplicationContext() { 2 this.reader = new AnnotatedBeanDefinitionReader(this); 3 this.scanner = new ClassPathBeanDefinitionScanner(this); 4 }
需要创建一个reader和一个scanner。
从上面的代码可以看出两个构造方法的参数都是上下文。这里看下这个上下文类的继承实现关系。看出上下文是包含BeanDefinitionRegistry的功能。
AnnotatedBeanDefinitionReader用于操作BeanDefinition。
ClassPathBeanDefinitionScanner用于扫描路径下的文件,利用classLoader加载类然后生成BeanDefinition。
看下AnnotatedBeanDefinitionReader,主要包含的BeanDefinitionRegistry实际操作BeanDefinition的、ConditionEvaluator用于完成条件注解的解析和判断(也就是处理注解的)。
1 public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) { 2 Assert.notNull(registry, "BeanDefinitionRegistry must not be null"); 3 Assert.notNull(environment, "Environment must not be null"); 4 this.registry = registry; 5 this.conditionEvaluator = new ConditionEvaluator(registry, environment, null); 6 AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry); 7 }
看下ClassPathBeanDefinitionScanner。
1 private final BeanDefinitionRegistry registry; 2 3 private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults(); 4 5 private String[] autowireCandidatePatterns; 6 7 private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator(); 8 9 private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
主要包换的也就是BeanDefinitionRegistry、autowireCandidatePatterns、beanNameGenerator、scopeMetadataResolver都是为了解析类转换成BeanDefinition服务的。
创建过后的context包含如下内容:
可以看到beanFactory已经被创建。
里面的beanDefinationMap只包换初始META-INFO里面的六个类。
context实现了BeanDefinition的接口,但是并没有持有BeanDefinitionMap,是DefaultListableBeanFactory里面持有的,也就是实际操作的是DefaultListableBeanFactory里面的BeanDefinition。DefaultListableBeanFactory是GenericApplicationContext持有的。
看GenericApplicationContext也可以发现,对于BeanDefinition实际的操作都在DefaultListableBeanFactory里,GenericApplicationContext对DefaultListableBeanFactory做了代理。
以上是关于spring boot 源码分析-------ApplicationContext的主要内容,如果未能解决你的问题,请参考以下文章
spring boot 源码分析-------ApplicationContext
SpringBoot 源码解析 ----- Spring Boot的核心能力 - 内置Servlet容器源码分析(Tomcat)