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做了代理。

原文地址:https://www.cnblogs.com/avalon-merlin/p/10538118.html

时间: 2024-08-30 01:49:30

spring boot 源码分析-------ApplicationContext的相关文章

Spring boot 源码分析(前言)

开坑达人 & 断更达人的我又回来了 翻译的坑还没填完,这次再开个新坑= = 嗯,spring boot的源码分析 本坑不打算教你怎么用spring boot = = 也不打算跟你讲这玩意多方便 =  = 咱们就看代码= = 然后呢... 任何源码分析总要有个开始 而本坑,我打算从run方法开始 SpringApplication.run(Main.class, args); 然后碰见什么讲什么. 嗯就酱紫. 另外,老规矩: 更新看心情,回车看心情 欢迎催更,欢迎批评指正 嗯就酱紫吧. 下一章讲S

【Spring Boot源码分析】@EnableAutoConfiguration注解(一)@AutoConfigurationImportSelector注解的处理

Java及Spring Boot新手,首次尝试源码分析,欢迎指正! 一.概述 @EnableAutoConfiguration注解是Spring Boot中配置自动装载的总开关.本文将从@EnableAutoConfiguration入手,尝试通过源码分析增强对Spring Boot的理解. 所用版本:Spring Boot 2.2.0.M5 + Spring Framework 5.2.0.RC1 1. 功能的实现:(Spring Boot部分) boot.autoconfigure.Enab

Spring boot 源码分析(一)SpringApplication.run(上)

SpringApplication.run(Main.class, args); 从这个方法开始讲吧: public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) { return run(new Class<?>[] { primarySource }, args); } ConfigurableApplicationContext 这个接口,熟悉spring源码

曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean definition的?

写在前面的话 相关背景及资源: 曹工说Spring Boot源码系列开讲了(1)-- Bean Definition到底是什么,附spring思维导图分享 工程代码地址 思维导图地址 工程结构图: 大体思路 总体来说,bean definition是什么,我们前面几讲,说了个大概了:目前,我们将聚焦于怎么获取bean definition. 我们这次做个实验,就是将bean definition(一共两个bean,有依赖关系,依赖是手动指定的)定义在json文件内,然后自定义一个applicat

曹工说Spring Boot源码(18)-- Spring AOP源码分析三部曲,终于快讲完了 (aop:config完整解析【下】)

写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解 曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean de

曹工说Spring Boot源码(16)-- Spring从xml文件里到底得到了什么(aop:config完整解析【上】)

写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解 曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean de

曹工说Spring Boot源码(19)-- Spring 带给我们的工具利器,创建代理不用愁(ProxyFactory)

写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解 曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean de

曹工说Spring Boot源码(24)-- Spring注解扫描的瑞士军刀,asm技术实战(上)

写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean Definition到底是什么,咱们对着接口,逐个方法讲解 曹工说Spring Boot源码(3)-- 手动注册Bean Definition不比游戏好玩吗,我们来试一下 曹工说Spring Boot源码(4)-- 我是怎么自定义ApplicationContext,从json文件读取bean de

Spring Boot源码中模块详解

Spring Boot源码中模块详解 一.源码 spring boot2.1版本源码地址:https://github.com/spring-projects/spring-boot/tree/2.1.x 二.模块 Spring Boot 包含许多模块,以下是一些简单的概述: 1,spring-boot 为Spring Boot其他部分功能提供主要的lib包,其中包含:(1)SpringApplication类提供了静态便利的方法使编写独立的SpringApplication更加容易.它唯一的任