上一篇文章分析到createBean执行到了doCreateBean方法:
自定义的WelcomeController下面有一个成员变量WelcomeService被@Autowired标签标记
进入到doCreateBean方法里:
1 | java复制代码protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
首先定义了一个包装类BeanWrapper
,
该接口是spring提供的用于操作bean中属性的工具,使用它可以直接修改bean里面的属性,BeanWrapperImpl
是AbstractNestablePropertyAccessor
的子类,BeanWrapper
的实现类,通过父类使得其具有处理属性的能力。
回到doCreateBean,接下来判断BeanDefinition是否是单例,如果是的话尝试从缓存中获取FactoryBean实例,如果获取不到就会执行
1 | java复制代码instanceWrapper = createBeanInstance(beanName, mbd, args); |
进入到createBeanInstance里:
1 | java复制代码protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { |
第一行会再次调用resolveBeanClass尝试去获取bean里面的class对象,之后看看class的访问修饰符,检查是否有权通过反射创建private的Class,如果bean使用了java自带的函数式接口Supplier,即工厂方法,就会调用工厂方法里的get方法来创建bean实例
1 | java复制代码@FunctionalInterface |
这里我们没有用到Supplier,就会看一下BeanDefinition里有没有定义Spring里的工厂方法,如果有则通过factory-method来返回实例。
如果不是上述两种方式,如果传入的args参数为空就会来到synchronized
代码块,先判断一下先前解析配置成BeanDefinition实例的时候,有没有获取到已经解析的构造函数,如果有就会调用
1 | java复制代码return autowireConstructor(beanName, mbd, null, null); |
进行有参构造函数的解析。
之后会使用带参的构造函数进行装配或者无参的构造函数进行装配。
1 | java复制代码return instantiateBean(beanName, mbd); |
进入到调用无参构造函数的方法里:
1 | java复制代码protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) { |
instantiate默认调用的是SimpleInstantiationStrategy类中的方法,在方法里会首先判断是否有look-up method等使用其他bean的替换方法的情况,如果有的话会使用cglib重写bean原本的方法,没有的话会制定同步代码块
1 | java复制代码@Override |
再回到instantiateBean方法,获取到了创建好的bean实例之后,就会将其包装到BeanWrapper里,包装好了之后还回去初始化
1 | java复制代码protected void initBeanWrapper(BeanWrapper bw) { |
initBeanWrapper主要是给wrapper设定上自定义类型转换工具
instantiateBean最终创建好的beanWrapper,此时就完成了createBeanInstance的调用。
回到doCreateBean,此时就会将创建好的instanceWrapper
的bean实例类型传入到applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
本文转载自: 掘金