SpringBoot&Spring
SpringApplication的run方法
首先会创建StopWatch来统计启动耗时。
获取所有的SpringApplicationRunListeners(默认有一个事件发布的Listener):—> getSpringFactoriesInstances来实例化SpringFactoriesLoader#loadSpringFactories META-INF/spring.factories
prepareEnvironment根据启动参数来准备环境
printBanner打印Banner
createApplicationContext创建ApplicationContext,根据webApplicationType创建servlet/reactive。
servlet:AnnotationConfigServletWebServerApplicationContext构建时注册5个默认处理器
默认:AnnotatedBeanDefinitionReader、ClassPathBeanDefinitionScanner
同时创建:DefaultListableBeanFactory
prepareContext准备上下文,springboot中,在这里注册一个application启动类。 这里通过BeanDefinitionLoader去注册一些核心的BenDefinition.
refreshContext刷新Context (核心):
refreshContext(context);
- prepareRefresh()//切换到活跃,初始化PropertySources 等处理
- obtainFreshBeanFactory()//获取BeanFactory -> XML解析 -> 封装BeanDefinition
- prepareBeanFactory(beanFactory)//准备BeanFactory 为BeanFactory配置ClassLoader还有添加一些后处理器(ApplicationContextAwareProcessor等)
- postProcessBeanFactory(beanFactory)//默认没有实现,留给子类实现 这时候默认的bean definitions已经加载,但是还没有实例化
- invokeBeanFactoryPostProcessors(beanFactory)//调用 Bean Factory 后处理器 ConfigurationClassBeanDefinitionReader.loadBeanDefinitions() 扫描classpath解析出所有的BeanDefinition
- registerBeanPostProcessors(beanFactory)//注册所有的BeanPostProcessor
- initMessageSource()//初始化MessageSource
- initApplicationEventMulticaster();//初始化一个事件管理器(applicationEventMulticaster)(springboot的事件发布就是通过这个来实现的)
- onRefresh()//由子类来处理,springboot会在这里启动tomcat
- registerListeners()//注册ApplicationListener来监听ApplicationEvent
- finishBeanFactoryInitialization(beanFactory)//实例化所有剩余的(非延迟初始化)单例。单例、非抽象、非懒加载
- finishRefresh()//清除缓存,初始化生命周期处理器,发布ContextRefresh事件
afterRefresh Context刷新后
告诉listeners started(context)
获取实现了ApplicationRunner和CommandLineRunner 的Bean来运行
告诉listeners running(context)
实例化过程
- 通过:FactoryMethod,有参构造,无参构造 来实例化,这时候属性为空。populateBean的时候来完成属性的注入。
- Autowired注解收集:applyMergedBeanDefinitionPostProcessor。
- AutoWiredAnnotationBeanPostProcessor(@Autowired、@Value)
- CommonAnnotationBeanPostProcessor(@Resource、@PostConstruct、@PreDestroy)
收集为 InjectionMetaData : 用于管理注入元数据的内部类。不用于直接应用。
inject() 方法会触发当前依赖注入属性的getBean。
- 依赖注入完成后,属性就有值了。
ConfigurationClassPostProcessor
收集(@Component @ComponentScan @Import @ImportSource @Configuration @Bean @PropertySources )
7.1 Xml解析和BeanDefinition封装,在步骤7中
obtainFreshBeanFactory方法
refreshBeanFactory() -> AbstractRefreshableApplicationContext#loadBeanDefinitions() 来解析成BeanDefinition
- XmlBeanDefinitionReader 来读取XML配置的Bean
- AnnotatedBeanDefinitionReader 来读取注解配置的Bean
BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor 来获取BeanFactory
postProcessBeanDefinitionRegistry() 提供了
BeanDefinitionRegistry
来注册、移除、获取 BD
BeanDefinition
- id Bean的唯一标识
- name 为id创建一个或多个别名
- beanClass bean的Class
- scope singleton或者是prototype
- primary是否是主要的
- parent 子类Bean定义它所引用的父类Bean
- lazy-init 是否懒初始化,true:BeanFactory启动时,false:Bean请求时
- autowireMode Bean自动装载方式。no、byName、byType、Constructor
- dependsOn Bean依赖的对象,会在之前创建好这些对象
- initMethod 初始化方法
- destroyMethod 销毁方法
- factoryMethod与factoryBean 创建Bean的工厂方法与工厂类
- MutablePropertyValues
MutablePropertyValues类,List
包含k-v XML解析的时候会解析属性配置:
1
2
3
4
5
6
7
8 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="driverClassName" value="${jdbc.driver}" />
<property name="maxActive" value="10" />
<property name="minIdle" value="5" />
</bean>
内置Processor (AnnotatedBeanDefinitionReader)
1 | 0 = "org.springframework.context.annotation.internalConfigurationAnnotationProcessor"///用来解析加了@Configuration的配置类,还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解。 |
后处理器
- 容器后处理器:BeanFactoryPostProcessor refreshContext()时执行一次
- Bean后处理器:BeanPostProcessor initializeBean()的时候穿插执行
BeanPostProcessor:可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。这里说的初始化方法,指的是下面两种:
1)bean实现了InitializingBean接口,对应的方法为afterPropertiesSet
2)在bean定义的时候,通过init-method设置的方法
InitializingBean
ApplicationContextAware
BeanNameAware
循环依赖
前提:单例的、允许循环依赖的、在创建中的 允许Bean提前暴露。
- 通过addSingletonFactory来建立beanName 与 ObjectFactory 的映射关系(这里就是三级缓存)。
- getSingleton() 方法会从这里来创建对象。 一级缓存、二级缓存、三级缓存
- ObjectFactory 的 getObject() 方法来获取对象。
二级缓存:不会走getEarlyBeanReference循环所有的BeanPostProcessor来拿对象。
三级缓存
ObjectFactory.
getEarlyBeanReference->wrapIfNecessary
正常情况:是在initializeBean中 - 初始化之后的后置处理器(AbstractAutoProxyCreator)中完成代理
只能存在单例,Prototype直接报错
depends on 优先getBean促使实例化
@Bean BeanDefinition中的FactoryMethod。
MergedBeanDefinitionPostProcessor
允许后处理器修改合并的 bean 定义。
doCreateBean中调用postProcessMergedBeanDefinition
//在bean实例化完毕后调用 可以用来修改merged BeanDefinition的一些properties 或者用来给后续回调中缓存一些meta信息使用
//这个算是将merged BeanDefinition暴露出来的一个回调
BeanDefinitionHolder的属性
- BeanDefinition beanDefinition
- String beanName
- String[] aliases