运行环境:jdk8,springboot-2.2.2java
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.2.RELEASE</version> </parent>
建立Spring IOC容器对象
问题:spring
- 容器在哪里建立?
- 容器的运行时类型是什么?
// 启动类 @SpringBootApplication public class BootApplication { public static void main(String[] args) { SpringApplication.run(BootApplication.class); } }
// 执行run方法时,建立Spring IOC容器。这里只是建立了容器对象,容器还未执行refresh方法 context = createApplicationContext();
SpringBoot
默认使用的容器类型是AnnotationConfigServletWebServerApplicationContext
springboot
Spring IOC容器结构分析
接下类分析下AnnotationConfigServletWebServerApplicationContext
spring-boot
下图的继承关系比较“吓人”,可是重点只有几个 this
-
GenericApplicationContext
code这个类是
AnnotationConfigServletWebServerApplicationContext
的父类,GenericApplicationContext
持有成员变量xmlprivate final DefaultListableBeanFactory beanFactory;
对象此成员变量的初始化是在调用
GenericApplicationContext
的无参构造器时执行的blogpublic GenericApplicationContext() { this.beanFactory = new DefaultListableBeanFactory(); }
-
DefaultListableBeanFactory
继承这个类是建立和管理bean实例的bean工厂
持有成员变量
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
保存最初的BeanDefinition
对象
其父类AbstractBeanFactory
持有成员变量
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256);
保存最终的BeanDefinition
对象,以后会调用其中的BeanDefinition
对象做为模板建立bean实例
其父类DefaultSingletonBeanRegistry
持有成员变量
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
保存建立完成的单实例bean
它还持有其余成员变量保存其余种类的bean实例
有了上述的继承关系AnnotationConfigServletWebServerApplicationContext
的对象将很是强大,这个对象将能够建立BeanDefinition
和bean实例,管理全部的BeanDefinition
和bean实例
补充
DefaultListableBeanFactory
的 beanDefinitionMap
和AbstractBeanFactory
的mergedBeanDefinitions
都保存了BeanDefinition
对象,那么建立bean实例时用谁作模板?
在AbStractApplicationContext
执行finishBeanFactoryInitialization(beanFactory)
方法建立剩余的全部非懒加载的单实例bean时
调用AbstractBeanFactory
的getMergedBeanDefinition
方法获取BeanDefinition
对象
会先调用抽象方法getBeanDefinition
(由DefaultListableBeanFactory
实现)
此方法会从DefaultListableBeanFactory
的beanDefinitionMap
中找BeanDefinition
找不到,抛异常;找到,对其加工,将其put到mergedBeanDefinitions
再从mergedBeanDefinitions
中获取并返回RootBeanDefinition
将其做为模板建立bean实例