Spring源码分析-SpringBoot启动
一、启动流程
-
createApplicationContext:
构造器会初始化
AnnotatedBeanDefinitionReader和ClassPathBeanDefinitionScanner,在AnnotatedBeanDefinitionReader构造器中,会调用AnnotationConfigUtils.registerAnnotationConfigProcessors -
prepareContext
-
postProcessApplicationContext
- beanNameGenerator
- resourceLoader
- conversionService
-
applyInitializers
-
listeners.contextPrepared(context)
-
load:在这里会将启动类的bd注册到容器,以便后边根据启动类导入 -
refreshContext --> refresh:
-
prepareRefresh
-
obtainFreshBeanFactory --> refreshBeanFactory:
refreshBeanFactory是个重载方法,分别对应纯注解启动的
GenericApplicationContext,以及xml注入使用的AbstractRefreshableApplicationContext:loadBeanDefinitions -
prepareBeanFactory
-
invokeBeanFactoryPostProcessors: -
registerBeanPostProcessors:按顺序实例化bean并注册到容器:priorityOrdered->ordered->nonOrdered->internal
-
-
onRefresh
-
finishBeanFactoryInitialization
-
afterRefresh
- callRunners:获取、排序并执行
ApplicationRunner和CommandLineRunner
- callRunners:获取、排序并执行
-
二、AbstractRefreshableApplicationContext:loadBeanDefinitions
--> XmlBeanDefinitionReader#loadBeanDefinitions:遍历资源(配置文件,例如xml),注册bd
--> XmlBeanDefinitionReader#doLoadBeanDefinitions
--> XmlBeanDefinitionReader#doLoadBeanDefinitions
--> XmlBeanDefinitionReader:
doLoadDocument:返回解析好的Document
registerBeanDefinitions--> doRegisterBeanDefinitions --> parseBeanDefinitions:
-
parseDefaultElement:解析各种标签以及标签属性,生成bd,注册到容器:<bean class="com.xiaoxizi.spring.service.AccountServiceImpl" id="accountService" name="aaa" scope="singleton" abstract="false" parent="parent" autowire="byType" autowire-candidate="true" primary="true" depends-on="depends" init-method="init" destroy-method="destroy" factory-bean="factoryBean" factory-method="factoryMethod" lazy-init="false" > <description>一些描述</description> <constructor-arg ref="bean" value="固定值" type="参数类型" name="参数名称" index="索引"/> <property name="key1" value="固定值" ref="beanRef"/> <meta key="key1" value="固定值"/> <qualifier type="bean类型" value="限定的bean的名称"/> <lookup-method name="方法名" bean="bean名称"/> <replaced-method name="方法名" replacer="bean名称"> <arg-type>参数类型,用于缺人唯一的方法</arg-type> </replaced-method> </bean>属性 作用 class 指明bean所属的类 id bean在ioc容器中的唯一标识,如果不填将取别名中的第一个 name bean的别名 scope bean的scope,一般日常开发都是使用默认的singleton单例,还有prototype多例。事实上web环境还有request和session。而且我们也可以自定义scope(之后会讲到的) abstract 是否是抽象的,抽象的bean不会被实例化,只能被继承,用的很少 parent 指定父bean,可以结合abstract一起使用,当然parent指向的bean并不一定要是抽象的 autowire 被自动装配的模式,有byType,byName等可选 autowire-candidate 是否能被其他bean自动装配,false的话该bean将不能被其他bean注入,读者可以自行尝试一下 primary 如果自动装配时匹配到多个bean,标记为primary的bean将被优先注入。 depends-on 依赖,依赖的bean将会先被实例化 init-method bean实例化之后将会调用的方法 destroy-method bean销毁时将会调用的方法,需要主要的是,只有单例的bean,IOC容器才持有其引用,IOC容器销毁 --> bean销毁时才会触发这个方法。 factory-bean 工厂bean的名称,需要与factory-method结合使用,创建bean时将会调用factory-bean.factory-method()来获取当前类实例。 factory-method 工厂bean方法,其实@Bean注解就是通过factory-bean、factory-method属性的功能实现的。 lazy-init 是否是懒加载的 -
parseCustomElement:
-
getNamespaceURI(ele):获取标签对应的名称空间
-
readerContext.getNamespaceHandlerResolver().resolve(namespaceUri):根据名称空间获取对应的处理器
-
getHandlerMappings:实际是去
META-INF/spring.handlers文件加载ns->handler的键值对到map中 -
Object handlerOrClassName = handlerMappings.get(namespaceUri):获取出来的可能是个handler对象,或者是一个类名
如果是类名(以ContextNamespaceHandler为例):
namespaceHandler = BeanUtils.instantiateClass(handlerClass)
namespaceHandler.init:
注册一系列的Parser:
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser())
...
handlerMappings.put(namespaceUri, namespaceHandler)
-
-
handler.parse(以ContextNamespaceHandler为例):实际调用的是父类NamespaceHandlerSupport的方法
- findParserForElement:从之前注册的一系列parser中根据标签获取
- parser.parse:
- 获取basePackage
- 获取并配置ClassPathBeanDefinitionScanner
- scanner.doScan:返回一个bd集合
findCandidateComponents(basePackage) - 遍历每个bd:
AnnotationConfigUtils.processCommonDefinitionAnnotations:处理@lazy、@Primary、@dependsOn、@role、@description等注解 - registerBeanDefinition
- registerComponents:
AnnotationConfigUtils.registerAnnotationConfigProcessors:
ConfigurationClassPostProcessor:处理配置类 - AutowiredAnnotationBeanPostProcessor:处理@Autowire,@Value
- CommonAnnotationBeanPostProcessor:处理@Resource、@PostConstruct、@PreDestroy
- ...
-

浙公网安备 33010602011771号