< beanclass= "org.javaboy.bean.User"id= "user"autowire= "constructor">
</ bean>
如果添加了 autowire="constructor" 就表示要通过构造方法进行注入,那么这里也会进入到 if 中 。
if 里边剩下的几个条件都好说,就是看是否有配置构造方法参数,如果配置了,那么也直接调用相应的构造方法就行了 。
这里最终执行的是 autowireConstructor 方法,这个方法比较长,我就不贴出来了,和大家说一说它的思路:
- 首先把能获取到的构造方法都拿出来,如果构造方法只有一个,且目前也没有任何和构造方法有关的参数,那就直接用这个构造方法就行了 。
- 如果第一步不能解决问题,接下来就遍历所有的构造方法,并且和已有的参数进行参数数量和类型比对,找到合适的构造方法并调用 。
ctors = mbd.getPreferredConstructors;
if(ctors != null) {
returnautowireConstructor(beanName, mbd, ctors, null);
}
这块代码看字面好理解,就是获取到主构造方法,不过这个是针对 Kotlin 的,跟我们 Java 无关,我就不啰嗦了 。
2.6 instantiateBean
最后就是 instantiateBean 方法了,这个方法就比较简单了,我把代码贴一下小伙伴们应该自己都能看明白:
protectedBeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd){
try{
Object beanInstance = getInstantiationStrategy.instantiate(mbd, beanName, this);
BeanWrapper bw = newBeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
returnbw;
}
catch(Throwable ex) {
thrownewBeanCreationException(mbd.getResourceDeion, beanName, ex.getMessage, ex);
}
}
@Override
publicObject instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner){
// Don't override the class with CGLIB if no overrides.
if(!bd.hasMethodOverrides) {
Constructor<?> constructorToUse;
synchronized(bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if(constructorToUse == null) {
finalClass<?> clazz = bd.getBeanClass;
if(clazz.isInterface) {
thrownewBeanInstantiationException(clazz, "Specified class is an interface");
}
try{
constructorToUse = clazz.getDeclaredConstructor;
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch(Throwable ex) {
thrownewBeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
returnBeanUtils.instantiateClass(constructorToUse);
}
else{
// Must generate CGLIB subclass.
returninstantiateWithMethodInjection(bd, beanName, owner);
}
}
从上面小伙伴么可以看到,本质上其实就是调用了 constructorToUse = clazz.getDeclaredConstructor; ,获取到一个公开的无参构造方法,然后据此创建一个 Bean 实例出来 。
3. 小结
好了,这就是 Spring 容器中 Bean 的创建过程,我这里单纯和小伙伴们分享了原始 Bean 的创建这一个步骤,这块内容其实非常庞杂,以后有空我会再和小伙伴们分享 。
最后,给上面分析的方法生成了一个时序图,小伙伴们作为参考 。

文章插图
其实看 Spring 源码,松哥最大的感悟就是小伙伴们一定要了解 Spring 的各种用法,在此基础之上,源码就很好懂,如果你只会 Spring 一些基本用法,那么源码一定是看得云里雾里的 。
END
推荐阅读
- SpringBoot中使用Cache提升接口性能详解
- 通过Docker和Kubernetes实现容器化的自动伸缩
- 花生油的保存方法 花生油的保存方法用什么容器放花生油最好
- 杨梅泡酒要用什么酒 杨梅泡酒用什么容器比较好
- 微波炉热菜用什么器皿 用微波炉热菜用什么容器
- 简单起泡胶怎么做? 简单起泡胶怎么做
- 微波炉不能用什么容器 微波炉不能用什么容器加热饭菜
- 玻璃容器能放微波炉吗 玻璃容器能放微波炉吗安全吗
- 使用微波炉可以使用金属容器和空载吗 使用微波炉能不能用金属容器
- 空气炸锅能放什么容器 空气炸锅放什么容器最好
