afumu
afumu
发布于 2019-09-13 / 5 阅读
0
0

Spring源码解析系列一:配置类的初始化过程

从今天开始,准备写关于Spring源码的博客,那么废话不多说, 咱们开始搞!

1.环境准备

1).看图:

PersonService类:

@Component
public class PersonService {
  public void run(){
    System.out.println("run方法执行了");
  }
}

SpringConfiguration类:

@ComponentScan("my.blog")
public class SpringConfiguration {
}

Test01类:

public class Test01 {
  public static void main(String[] args) {
    //这个构造方法会把Spring所有的环境都准备好
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringConfiguration.class);
    PersonService person = ac.getBean(PersonService.class);
    person.run();
  }
}

2.介绍:注解配置应用上下文

AnnotationConfigApplicationContext 顾名思义:注解配置应用上下文, 我在演示当中使用的是注解的方式

所以需要 new AnnotationConfigApplicationContext 这个对象.

如果采用的是xml的配置方式 则需要 new ClassPathXmlApplicationContext ,这个应该我不用多说,我想你应该懂的!

那么这个实例化对象的过程,Spring到底中干了哪些见不得人的事呢? 接下来跟着我一起去揭开他的神秘面纱!

我们点击 new AnnotationConfigApplicationContext 看一下他的构造方法:

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
    //这个类有父类,所以会先初始化父类的构造方法,接着初始化自己的构造方法
//调用无参构造方法进行初始化一个读取器和扫描仪
this();

   //这个方法的作用:主要是把配置类的信息加载进工厂中
   //在这里需要你记住一个类:DefaultListableBeanFactory,后面会非常的重要
register(annotatedClasses);

//实例化所有被加了组件的对象
refresh();
}

我们发现这个构造函数的参数可以一次性传多个配置类,后面代码中其实会遍历annotatedClasses 这个数组

我们看一下 this() 干了哪些事?

  public AnnotationConfigApplicationContext() {
    //这里也会先初始化父类的构造方法
    //创建一个读取被加了注解的bean读取器 ,这个读取器到底什么鬼,不是这节的重点,可以先忽略
    //你就知道他创建了一个读取器就完事了
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}

我们回到 register(annotatedClasses);这个方法, 这个方法就是本节的大哥,我们现在就要去看看,他为Spring干了哪些脏活!

3.加载配置类

我们点击 register(annotatedClasses)

嗯…,好像没啥用!

点击 this.reader.register(annotatedClasses); 方法

这时候,我们发现这个方法开始遍历annotatedClasses 数组,由此我们可以一次性写多个配置文件传给构造方法的

开始遍历annotatedClasses(注意:本次演示中,我只添加了一个配置类), 调用 registerBean(annotatedClass);

我们这时候点击 registerBean(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) {
        //(1)(解析:查看下面图)
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    //这个不是重点,跳过
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
  return;
}
    
     //这个不是重点,跳过 instanceSupplier为null值
abd.setInstanceSupplier(instanceSupplier);

//(2)得到类的作用域 单例还是多例(解析:查看下面图)
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    
//把类的作用域赋值给AnnotatedGenericBeanDefinition对象
abd.setScope(scopeMetadata.getScopeName());

//生成配置类的名称,如果@Component没有对应的名称   (我没有加名称)
    //默认是类的小驼峰式命名称 (所有此时beanName为springConfiguration)
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

/**
 * (3)把AnnotatedGenericBeanDefinition对象传进
 * 然后获取获取元数据metadata对象,判断元数据对象中是否存在lazy,DependsOn,Primary Role 等注解
 * 如果有这些注解,则在AnnotatedGenericBeanDefinition对象中记录
 */
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

//qualifiers本身传过来的就是一个 null 值
//如果不手动传,永远为空值,没有意义
if (qualifiers != null) {
  for (Class&lt;? extends Annotation&gt; 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);
}
    
     //(4)把abd放进去,赋值给了成员变量beanDefinition
//把BeanName赋值进去,可以说是增强版的abd对象
//查看后面的代码发现,其实definitionHolder就只是起到一个临时容器的作用
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

//这个比较复杂,以后可以讲 和本节无关
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

//(5)现在又把增强版的 definitionHolder 放到registry这个容器中
//BeanDefinitionRegistry 顾名思义 就是注册BeanDefinition的
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

1).我们查看代码AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);干了哪些事 ?

通过debug 查看 abd 对象内容

总结:

  1. 根据指定的配置类,创建一个GenericBeanDefinition对象

  2. 这个GenericBeanDefinition对象包含了该类的一些元信息,例如注解信息: scope,lazy,ComponentScan等注解

  3. 这些注解存储在 GenericBeanDefinition中的 元数据(metadata)对象中

  4. 元数据对象有一个注解集合 annotations ,存储所有的注解信息

2).接下来查看 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);

执行完这个abd.setScope(scopeMetadata.getScopeName());方法后

3).查看 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

点击进入

额…, 这个方法好像也没啥…

把传进的abd对象拆开,又传了abd对象和abd.getMetadata()元数据对象

点击 processCommonDefinitionAnnotations(abd, abd.getMetadata());

  static void processCommonDefinitionAnnotations(AnnotatedBeanDefinition abd, AnnotatedTypeMetadata metadata) {
    //判断当前的类是否加了lazy注解
    AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
//如果不为null,则把AnnotatedBeanDefinition中的 lazyInit 默认的false 修改为true
if (lazy != null) {
  abd.setLazyInit(lazy.getBoolean(&quot;value&quot;));
}
else if (abd.getMetadata() != metadata) {
  lazy = attributesFor(abd.getMetadata(), Lazy.class);
  if (lazy != null) {
    abd.setLazyInit(lazy.getBoolean(&quot;value&quot;));
  }
}
    
//判断元数据对象中时候有@Primary,默认时候primary是 false ,如果有则该为true
if (metadata.isAnnotated(Primary.class.getName())) {
  abd.setPrimary(true);
}
    
//判断时候有@DependsOn注解
AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
if (dependsOn != null) {
  abd.setDependsOn(dependsOn.getStringArray(&quot;value&quot;));
}

//判断时候有@Role注解
AnnotationAttributes role = attributesFor(metadata, Role.class);
if (role != null) {
  abd.setRole(role.getNumber(&quot;value&quot;).intValue());
}
    
//判断时候有@Description注解
AnnotationAttributes description = attributesFor(metadata, Description.class);
if (description != null) {
  abd.setDescription(description.getString(&quot;value&quot;));
}
}

总结:

  1. 把AnnotatedGenericBeanDefinition对象传进去

  2. 获取元数据metdata对象,判断元数据对象中是否存在lazy,DependsOn,Primary Role 等注解

  3. 如果有这些注解,则在AnnotatedGenericBeanDefinition对象中记录

4).查看 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

debug 发现

5).查看 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);

点击进入

public static void registerBeanDefinition(
      BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
      throws BeanDefinitionStoreException {
//在这里又获取beanName的名称
String beanName = definitionHolder.getBeanName();

//现在把definitionHolder拆分了,又把abd对象拿出来了
//似乎definitionHolder就只是封装了一下,然后又给拆分, 可以理解为一个临时的容器
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

 //这个不重要,spring当中处理别名的
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
  for (String alias : aliases) {
    registry.registerAlias(beanName, alias);
  }
}
}

我们点击 registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

发现是一个接口, 按住快捷键 Ctrl + Alt + B ,有三个实现类,前面就你留意的 DefaultListableBeanFactory 在这里出现了,

选择 DefaultListableBeanFactory

  @Override
  public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
      throws BeanDefinitionStoreException {
   //-------------------------------------------------------------------------------
    Assert.hasText(beanName, "Bean name must not be empty");
    Assert.notNull(beanDefinition, "BeanDefinition must not be null");
if (beanDefinition instanceof AbstractBeanDefinition) {
  try {
    ((AbstractBeanDefinition) beanDefinition).validate();
  }
  catch (BeanDefinitionValidationException ex) {
    throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
        &quot;Validation of bean definition failed&quot;, ex);
  }
}
    //查看该bean时候在map集合中存储过
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
  if (!isAllowBeanDefinitionOverriding()) {
    throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
  }
  else if (existingDefinition.getRole() &lt; beanDefinition.getRole()) {
    // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
    if (logger.isInfoEnabled()) {
      logger.info(&quot;Overriding user-defined bean definition for bean '&quot; + beanName +
          &quot;' with a framework-generated bean definition: replacing [&quot; +
          existingDefinition + &quot;] with [&quot; + beanDefinition + &quot;]&quot;);
    }
  }
  else if (!beanDefinition.equals(existingDefinition)) {
    if (logger.isDebugEnabled()) {
      logger.debug(&quot;Overriding bean definition for bean '&quot; + beanName +
          &quot;' with a different definition: replacing [&quot; + existingDefinition +
          &quot;] with [&quot; + beanDefinition + &quot;]&quot;);
    }
  }
  else {
    if (logger.isTraceEnabled()) {
      logger.trace(&quot;Overriding bean definition for bean '&quot; + beanName +
          &quot;' with an equivalent definition: replacing [&quot; + existingDefinition +
          &quot;] with [&quot; + beanDefinition + &quot;]&quot;);
    }
  }
  this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
  if (hasBeanCreationStarted()) {
    // Cannot modify startup-time collection elements anymore (for stable iteration)
    synchronized (this.beanDefinitionMap) {
      this.beanDefinitionMap.put(beanName, beanDefinition);
      List&lt;String&gt; updatedDefinitions = new ArrayList&lt;&gt;(this.beanDefinitionNames.size() + 1);
      updatedDefinitions.addAll(this.beanDefinitionNames);
      updatedDefinitions.add(beanName);
      this.beanDefinitionNames = updatedDefinitions;
      removeManualSingletonName(beanName);
    }
  }
 //---------------------------------------------------------------------------------------
        //前面的代码都是一些判断,验证不是重点
        //重点是这里的代码,前方高能
  else {
    //在这个方法中就把 beanDefinition 存储在 DefaultListableBeanFactory的map集合中
    //顾名思义,beanDefinitionMap就是一个存储beanDefinition的map集合
    //在这个集合当中还有Spring当中本身已经初始好的对象
    this.beanDefinitionMap.put(beanName, beanDefinition);
    //把beanName存储在这个list集合中
    this.beanDefinitionNames.add(beanName);
    //这个是去重的,不是重点
    removeManualSingletonName(beanName);
  }
  this.frozenBeanDefinitionNames = null;
}

if (existingDefinition != null || containsSingleton(beanName)) {
  resetBeanDefinition(beanName);
}
}

this.beanDefinitionMap.put(beanName, beanDefinition); 之前

this.beanDefinitionMap.put(beanName, beanDefinition); 之后

this.beanDefinitionNames.add(beanName); 之前

this.beanDefinitionNames.add(beanName); 之后

整个配置类的加载过程就执行完了,最后总结一下 register(annotatedClasses); 都干了哪些事?

  1. 加载配置类的元数据 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);

  2. 给abd对象设置作用域

  3. 遍历元数据注解 ,判断时候存在某注解

  4. 把配置类信息对象存储到 DefaultListableBeanFactory的beanDefinitionMap集合中

  5. 把配置类的名称存储到 DefaultListableBeanFactory的 beanDefinitionNames 集合中


评论