- instantiateBean(beanName, mbd); 使用默认构造方法实例化对象。
1 | java复制代码protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { |
- autowireConstructor(beanName, mbd, ctors, args); 使用有参构造方法实例化对象。
1 | java复制代码protected BeanWrapper autowireConstructor( |
autowireConstructor使用特殊构造方法实例化对象,主要做了几步操作:
1.判断要用哪个构造方法实例化对象:constructorToUse,那些参数:argsToUse
2.先决定构造方法的最小参数个数:minNrOfArgs。
3.对所有的构造方法进行排序,排序规则:访问权限级别(public–protected–private) 和 参数数量(从多到小)
4.遍历所有构造方法,根据“最小参数个数”minNrOfArgs去判断构造方法是否符合
5.计算构造方法的“typeDiffWeight 差异量”,找到最小的差异量,spring就用这个构造方法实例化对象。
6.如果spring找到了多个差异量一样的,也符合最小参数个数的构造方法,就记录在ambiguousConstructors。
7.如果这个ambiguousConstructors一直存在,spring会在循环外面去exception
8.如果这个ambiguousConstructors为null,spring就会缓存找到的constructorToUse的构造方法
9.最后通过找到constructorToUse构造方法,进行实例化对象。
1.instanceWrapper = createBeanInstance(beanName, mbd, args);
至此,使用构造方法实例化对象的方法就解析到这里。创建的对象,就执行下面这步
2.addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这个很重要,主要将刚new的对象,存放在singletonFactories对象。主要是用来解决循环依赖。
3.populateBean(beanName, mbd, instanceWrapper);
但是这个时候,对象还没进行属性赋值,需要调用该方法进行属性赋值
- populateBean(beanName, mbd, instanceWrapper);
1 | java复制代码protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { |
这里进行属性赋值,主要是调用了两个BeanPostProcessor进行属性赋值。
1.AutowiredAnnotationBeanPostProcessor(处理@Autowired注解)
2.CommonAnnotationBeanPostProcessor(处理@Resource、@PostConstruct和@PreDestroy注解)
- AutowiredAnnotationBeanPostProcessor源码解析
1 | java复制代码// @Autowired实现属性注入 |
进行属性赋值,就可能会出现循环依赖的情况:
例如:A类有一个B类的属性,B类有一个A类的属性。
那么在属性填充的时候,就会出现在创建A对象的时候,然后自动装配B,那么spring也会去创建B对象。那么这个时候,就会有一个循环依赖的情况。
那么spring是怎么解决循环依赖的?
- 在处理循环依赖的情况,spring主要用了3个map,1个list,最重要的就是singletonFactories
1 | java复制代码//这个时候bean已经被创建出来,但是还没进行属性装配 |
至此,spring对bean的实例化过程,就解析到这里了。
下面上spring实例化过程的流程图:
本文转载自: 掘金