SpringBoot下Spring IOC容器的结构

 

运行环境:jdk8,springboot-2.2.2


    org.springframework.boot
    spring-boot-starter-parent
    2.2.2.RELEASE

创建Spring IOC容器对象

问题:

  • 容器在哪里创建?
  • 容器的运行时类型是什么?
// 启动类
@SpringBootApplication
public class BootApplication {
    public static void main(String[] args) {
            SpringApplication.run(BootApplication.class);
    }
}
// 执行run方法时,创建Spring IOC容器。这里只是创建了容器对象,容器还未执行refresh方法
context = createApplicationContext();

SpringBoot默认使用的容器类型是AnnotationConfigServletWebServerApplicationContext

Spring IOC容器结构分析

接下类分析下AnnotationConfigServletWebServerApplicationContext

下图的继承关系比较“吓人”,但是重点只有几个 SpringBoot下Spring IOC容器的结构_第1张图片

  • GenericApplicationContext

    这个类是AnnotationConfigServletWebServerApplicationContext的父类,GenericApplicationContext持有成员变量

    private final DefaultListableBeanFactory beanFactory;

    此成员变量的初始化是在调用GenericApplicationContext的无参构造器时执行的

    public GenericApplicationContext() {
        this.beanFactory = new DefaultListableBeanFactory();
    }
    
  • DefaultListableBeanFactory

    这个类是创建和管理bean实例的bean工厂

SpringBoot下Spring IOC容器的结构_第2张图片

持有成员变量

private final Map beanDefinitionMap = new ConcurrentHashMap<>(256);

保存最初的BeanDefinition对象

其父类AbstractBeanFactory持有成员变量

private final Map mergedBeanDefinitions = new ConcurrentHashMap<>(256);

保存最终的BeanDefinition对象,之后会调用其中的BeanDefinition对象作为模板创建bean实例

​ 其父类DefaultSingletonBeanRegistry持有成员变量

private final Map singletonObjects = new ConcurrentHashMap<>(256);

​ 保存创建完成的单实例bean

​ 它还持有其他成员变量保存其他种类的bean实例

有了上述的继承关系AnnotationConfigServletWebServerApplicationContext的对象将非常强大,这个对象将可以创建BeanDefinition和bean实例,管理所有的BeanDefinition和bean实例

补充

DefaultListableBeanFactorybeanDefinitionMapAbstractBeanFactorymergedBeanDefinitions都保存了BeanDefinition对象,那么创建bean实例时用谁做模板?

AbStractApplicationContext执行finishBeanFactoryInitialization(beanFactory)方法创建剩余的所有非懒加载的单实例bean时

调用AbstractBeanFactorygetMergedBeanDefinition方法获取BeanDefinition对象

会先调用抽象方法getBeanDefinition(由DefaultListableBeanFactory实现)

此方法会从DefaultListableBeanFactorybeanDefinitionMap中找BeanDefinition

找不到,抛异常;找到,对其加工,将其put到mergedBeanDefinitions

再从mergedBeanDefinitions中获取并返回RootBeanDefinition

将其作为模板创建bean实例

你可能感兴趣的:(java,spring,设计模式,python,类)