程序员spring bootspring boot源码解析

SpringBoot启动 源码深度解析(一)

2020-05-09  本文已影响0人  凡毓不凡

SpringBoot 版本 : 2.2.1.RELEASE
入口类: SpringApplication;SpringApplicationBuilder
说明 : 由于SpringBoot建立在Spring之上,所以分析SpringBoot的启动过程其实与Spring是交错进行的,分析的时候会顺带将一些Spring的扩展点也提到
注:本文主要讲解一些比较重要的关键步骤,不能面面俱到,若有疑问,随时保持沟通

SpringBoot启动 源码深度解析(二)
SpringBoot启动 源码深度解析(三)
SpringBoot启动 源码深度解析(四)

1. 启动SpringBoot应用

@SpringBootApplication(scanBasePackages="com.union.autoseller")
public class SpringCloudDockerWebApplication {
    public static void main(String[] args) {
        new SpringApplicationBuilder(SpringCloudDockerWebApplication.class)
                .main(SpringVersion.class)
                .run(args);
    }
}
@SpringBootApplication
public class SpringCloudDockerWebApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudDockerWebApplication .class, args);
    }
}

2. SpringApplication.run(String... args) 函数

image.png
// beanFactory中添加比较器实例
AnnotationAwareOrderComparator
// beanFactory中添加AutowireCandidateResolver得实例化对象,用来处理@Lazy注解 和 @qualifier注解
ContextAnnotationAutowireCandidateResolver

注册所有注解配置处理器bean定义:

// registry中注册bean定义, 用来处理配置类
ConfigurationClassPostProcessor
// registry中注册bean定义,用来处理@Autowired
AutowiredAnnotationBeanPostProcessor
// registry中注册bean定义,但是前提是否启用jsr250支持():javax.annotation.Resource。用来处理@PostConstruct注解与@PreDestroy注解
CommonAnnotationBeanPostProcessor
// registry中注册bean定义, 检查是否提供JPA support,即有没有javax.persistence.EntityManagerFactory类,有的话并且需要引入spring-orm框架,然后才会注册当前处理器。
PersistenceAnnotationBeanPostProcessor
// registry中注册bean定义,当执行上下文得preInstantiateSingletons()方法之后,会触发SmartInitializingSingleton#afterSingletonsInstantiated()得回调,用来处理带有@EventListener注解得类,然后通过默认实现DefaultEventListenerFactory创建ApplicationListener实例
EventListenerMethodProcessor
// registry中注册bean定义,EventListenerFactory得默认实现,,生成ApplicationListener实例
DefaultEventListenerFactory
  1. 首先创建注解通用beanDefinetion类AnnotatedGenericBeanDefinition,类主包含一个成员:元数据对象类AnnotationMetadata
    构造器中同时会初始化这个元数据注解类,实例对象为:StandardAnnotationMetadata,这个类会保存参数class对应得所有注解
  2. 然后通过调用ConditionEvaluator类得方法shouldSkip方法判断类是否标注了@Conditional条件注解,没有得话直接false。表示不跳过,执行注册,有的话需要判断注解类得元数据是否包含@Configuration、@Component、@ComponentScan、@Import、@ImportResource、@Bean等注解。此时需要将配置阶段ConfigurationPhase设置为PARSE_CONFIGURATION,否则将配置阶段ConfigurationPhase设置为REGISTER_BEAN,递归当前shouldSkip方法。
  3. 设置完属性之后,由于ConfigurationPhase参数不为空,则下一次递归得时候将会跳过if(phase == null)判断逻辑,直接执行后面得逻辑。获取条件类Condition得实例,循环实例化,并添加到到临时集合中。然后对填充完得集合做一次排序。遍历集合判断类型是否是ConfigurationCondition类型,若是,则获取ConfigurationCondition实例对应配置得ConfigurationPhase,目前只有OnBeanCondition配置得是REGISTER_BEAN,若跟当前设置得相同并且不匹配matches方法,则应该跳过注册,否则可以执行注册流程。
  4. org.springframework.boot.autoconfigure.condition.SpringBootCondition#matches(org.springframework.context.annotation.ConditionContext, org.springframework.core.type.AnnotatedTypeMetadata),进到方法内,会调用org.springframework.boot.autoconfigure.condition.SpringBootCondition#getMatchOutcome()抽象方法,具体得条件解析去实现,执行匹配判断逻辑。
  5. 解析类得@Scope注解,调用org.springframework.context.annotation.AnnotationScopeMetadataResolver#resolveScopeMetadata方法
  6. 最后创建一个BeanDefinitionHolder对象用来保存beanDefinetion,接着调用definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry),若当前注解beanDefinetion@Scope属性为ScopedProxyMode.NO,表示不需要代理,则直接返回;否则判断代理模式是否为ScopedProxyMode.TARGET_CLASSCGLIB代理),调用org.springframework.context.annotation.ScopedProxyCreator#createScopedProxy 再调用org.springframework.aop.scope.ScopedProxyUtils#createScopedProxy实际得创建代理类得方法。

总结:@Conditional -> @Scope -> @common annotation :@Lazy/@DependsOn/@Role/@Description -> qualifier 属性验证 -> 自定义得BeanDefinitionCustomizer处理 -> 根据元数据对应得@Scope注解中具体得scopedProxyMode值判断是否需要启动代理模式 以及具体得代理模式 -> 注册bean定义

文章要是勘误或者知识点说的不正确,欢迎评论,毕竟这也是作者通过阅读源码获得的知识,难免会有疏忽!

上一篇 下一篇

猜你喜欢

热点阅读