運行環境: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實例