Spring源码之推断构造方法

文章目录

  • 前言
  • 一、什么是构造方法?
  • 二、在Spring中如何找到最合适的构造方法
    • 1、找出所有的构造方法
    • 2、遍历所有的构造方法获取到的构造方法
    • 3、找到构造方法之后,需要找出合适的构造方法
    • 4、整个推断构造方法的总结
    • 5、在获取所有构造方法之前还使用了DCL来保证线程安全问题。
  • 总结


前言

在Spring容器启动的时候会把所有的单例bean都给加载到容器中,但是在这些单例bean是如何被创建出来的呢?在Spring容器中,会使用推断构造方法将单例bean的构造方法找出来,找到最合适的构造方法进行对象的创建,具体找到构造方法,继续往下看?

一、什么是构造方法?

构造方法是一种特殊的方法,他是一个与类名相同的方法。对象创建就是通过构造方法来完成,其主要功能就是完成对象的初始化。

二、在Spring中如何找到最合适的构造方法

1、找出所有的构造方法

//先从缓存中有,则说明已经有创建过bean,最合适的构造方法在缓存中
Constructor<?>[] candidateConstructors = this.candidateConstructorsCache.get(beanClass);

//如果缓存中没有,通过反射获取该类的所有构造方法,则需要推断最合适的构造方法
rawCandidates = beanClass.getDeclaredConstructors();

2、遍历所有的构造方法获取到的构造方法

// 用来记录添加了@Autowired且required为true的构造方法,一个类中只能有一个required为true的构造方法
Constructor<?> requiredConstructor = null;
// 用来记录默认无参的构造方法
Constructor<?> defaultConstructor = null;
// kotlin相关,不用管
Constructor<?> primaryConstructor = BeanUtils.findPrimaryConstructor(beanClass);

下面流程图对应的就是循环遍历每一个构造方法的过程;

Spring源码之推断构造方法_第1张图片

3、找到构造方法之后,需要找出合适的构造方法

Spring源码之推断构造方法_第2张图片

4、整个推断构造方法的总结

  1. 找到Bean的所有构造方法;
  2. 循环每一个构造方法,如果使用了@Autowired注解就加入到候选candidates集合中;
  3. 如果找到了两个@Autowired的构造方法,就会抛出异常;
  4. 如果构造方法中有@Autowired的,但是也找到了一个默认的无参构造,那么也会加入到候选集合中,但是这个时候只有@Autowired中的required=false才会加入,也就是说,如果找到了一个默认无参构造方法,一个@Autowired属性required=true会被舍弃,只有找到@Autowired属性required=false,那么又找到一个无参构造方法,才会加入到candidates中,也就是说如果找到了@Autowired同时其属性required=false和一般无参构造方法一样,都会加入到后续列表中,Spring把它当做一个不确定的因素,需要后续继续推导;
  5. 如果找到的构造方法只有一个,并且这个构造方法的参数大于0,那么就放回这个构造方法;
  6. 如果前三个否不满足,也就是说bean中存在2个以上的构造方法,但是没有加@Autowired注解的构造,那么直接返回null;

5、在获取所有构造方法之前还使用了DCL来保证线程安全问题。

  1. 先从缓存中获取是否有构造方法;
  2. 如果没有则使用synchronized来锁住缓存;
  3. 目的是为了在当前线程获取锁对象之前,另一个线程能够操作完成;
  4. 获取所对象成功之后,再次查询缓存,如果获取成功,则直接返回;
  5. 如果获取失败,则开始推断构造方法;
  6. 最后还会将推断出的结果放入到缓存当中;

总结

以上就是我对Spring中的推断构造方法的总结,有疑问或其他问题,欢迎评论区见;

你可能感兴趣的:(java,javaweb,spring,java,后端)