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 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券