专栏首页须臾之余Spring5.0源码深度解析之Spring基于注解启动流程分析

Spring5.0源码深度解析之Spring基于注解启动流程分析

一:BeanFactory与ApplicationContext区别

ApplicationContext和BeanFactory两者都是用来加载bean的,但相比之下ApplicationContext提供了更多的扩展功能,简单一点说:ApplicationContext包含BeanFactory的所有功能。 通常建议比BeanFactory优先,除非在一些限制的场合。比如字节长度对内存有很大影响时。绝大多数“典型的”企业应用和系统,ApplicationContext就是你需要使用的。 BeanFactory负责读取Bean配置文档,管理bean的加载,实例化,维护Bean之间的依赖关系,负责Bean的生命周期。 ApplicationContext除了提供上述BeanFactory所能提供的功能外,还提供了更完整的框架功能: 国际化支持、资源访问、事件传递等...

下面来分析下,通过AnnotationConfigurationContext类图可知:

由类图可知AnnotationConfigApplicationContext的祖宗是ApplicationContext,所有可以这样写:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);

ApplicationContext 的子类

》》》》AnnotationConfigApplicationContext

》》》》ClassPathXmlApplicationContext

由上图可知:ApplicationContext继承BeanFactory实现扩展功能

ApplicationContext类图

ApplicationContext的祖宗是BeanFactory,实现增强

BeanFactory接口

二:AnnotationConfig启动流程源码分析

@Configuration
public class MyConfig {
    
}
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
for (int i=0;i<beanDefinitionNames.length;i++){
    System.out.println(beanDefinitionNames[i]);
}

输出结果

org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
myConfig

说明,能注入到spring容器中

下面源码分析:

ApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
   this();
   register(annotatedClasses);
   refresh();
}
public GenericApplicationContext() {
   this.beanFactory = new DefaultListableBeanFactory();
}
public AnnotationConfigApplicationContext() {
   this.reader = new AnnotatedBeanDefinitionReader(this);
   this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public void register(Class<?>... annotatedClasses) {
   Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
   this.reader.register(annotatedClasses); //基于注解方式启动
}
public void register(Class<?>... annotatedClasses) {
   for (Class<?> annotatedClass : annotatedClasses) {
      registerBean(annotatedClass);
   }
}
public void registerBean(Class<?> annotatedClass) {
   doRegisterBean(annotatedClass, null, null, null);
}
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
      @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {

   AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);    //BeanDefinition的作用:定义Bean的信息,AnnotatedGenericBeanDefinition 表示注解注入的配置bean
   if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {    //根据条件注入,判断是否需要注册
      return;
   }

   abd.setInstanceSupplier(instanceSupplier);    //设置回调的方式
   ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);    //判断启动类上是否加上@Scope作用域。没有加默认
   abd.setScope(scopeMetadata.getScopeName());
   String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//判断是否传递了BeanName,没有则默认类名首字母小写作为BeanName

   AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
   if (qualifiers != null) {
      for (Class<? extends Annotation> qualifier : qualifiers) {
         if (Primary.class == qualifier) {
            abd.setPrimary(true);
         }
         else if (Lazy.class == qualifier) {
            abd.setLazyInit(true);
         }
         else {
            abd.addQualifier(new AutowireCandidateQualifier(qualifier));
         }
      }
   }
   for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
      customizer.customize(abd);
   }

   BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
   definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
   BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

AnnotatedGenericBeanDefinition :表示注解形式启动的配置类注入spring IOC

String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
   if (definition instanceof AnnotatedBeanDefinition) {
      String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
      if (StringUtils.hasText(beanName)) {
         // Explicit bean name found.
         return beanName;
      }
   }
   // Fallback: generate a unique default bean name.
   return buildDefaultBeanName(definition, registry);
}
protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
   return buildDefaultBeanName(definition);
}

下面生成BeanId

AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
public static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd) {
   processCommonDefinitionAnnotations(abd, abd.getMetadata());
}

获取启动类是否添加了如下注解:

static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
   AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
   if (lazy != null) {
      abd.setLazyInit(lazy.getBoolean("value"));
   }
   else if (abd.getMetadata() != metadata) {
      lazy = attributesFor(abd.getMetadata(), Lazy.class);
      if (lazy != null) {
         abd.setLazyInit(lazy.getBoolean("value"));
      }
   }

   if (metadata.isAnnotated(Primary.class.getName())) {
      abd.setPrimary(true);
   }
   AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
   if (dependsOn != null) {
      abd.setDependsOn(dependsOn.getStringArray("value"));
   }

   if (abd instanceof AbstractBeanDefinition) {
      AbstractBeanDefinition absBd = (AbstractBeanDefinition) abd;
      AnnotationAttributes role = attributesFor(metadata, Role.class);
      if (role != null) {
         absBd.setRole(role.getNumber("value").intValue());
      }
      AnnotationAttributes description = attributesFor(metadata, Description.class);
      if (description != null) {
         absBd.setDescription(description.getString("value"));
      }
   }
}

下面看BeanDefinitionHolder包装类:

BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);//包装一层

BeanDefinition没有BeanName属性,转化为BeanDefinitionHolder添加了BeanName(BeanId),所以需要包装一下。

BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • SpringBoot源码分析 顶

    一:创建SpringApplication对象过程:new SpringApplication(primarySources)

    须臾之余
  • Spring5.0源码深度解析之SpringBean的生命周期

    说明单例默认是在容器被加载的时候初始化,多例是在每次获取Bean对象的时候初始化。

    须臾之余
  • 虚拟机的前世今生和Java内存区域 顶

    须臾之余
  • SpringFramework之AnnotatedBeanDefinitionReader

        AnnotatedBeanDefinitionReader没有继承任何类。

    克虏伯
  • Java 代码性能调优“三十六”策

    代码优化,一个很重要的课题。可能有些人觉得没用,一些细小的地方有什么好修改的,改与不改对于代码的运行效率有什么影响呢?这个问题我是这么考虑的,就像大海里面的鲸鱼...

    技术zhai
  • 基于MyBatis注解扩展,实现无需配置就可拥有增删改 顶

          如果项目本身基于SpringMVC+Mybatis构建,不需添加任何配置Mapper类只需继承

    用户2603479
  • DeepMind联手暴雪:星际II的玩家们,准备好对抗AI了吗(附论文)

    大数据文摘
  • 语义技术全线免费,人脸识别离线能力开放,百度为 AI 开发者带来福利

    AI 研习社按,在「燎原计划 2018」暨百度 AI 开发者实战营第二季北京站上,百度发布了三项重大消息:开放 EasyDL 平台、发布「深度学习工程师评价标准...

    AI研习社
  • 44个Java性能优化细节,教你提高代码运行的效率!

    代码优化的最重要的作用应该是:避免未知的错误。在代码上线运行的过程中,往往会出现很多我们意想不到的错误,因为线上环境和开发环境是非常不同的,错误定位到最后往往是...

    全栈自学社区
  • 为了故意刁难AI,科学家们制造了这1200个问题,超强AI被“打回原形”

    自从 IBM 的 Watson 在 “Jeopardy!” 智力问答竞赛中战胜人类冠军,人工智能真正理解人类语言这件事似乎变得触手可及。

    量子位

扫码关注云+社区

领取腾讯云代金券