Spring容器原始Bean是如何创建的?( 四 )


< beanclass= "org.javaboy.bean.User"id= "user"autowire= "constructor">
</ bean>
如果添加了 autowire="constructor" 就表示要通过构造方法进行注入,那么这里也会进入到 if 中 。
if 里边剩下的几个条件都好说,就是看是否有配置构造方法参数,如果配置了,那么也直接调用相应的构造方法就行了 。
这里最终执行的是 autowireConstructor 方法,这个方法比较长,我就不贴出来了,和大家说一说它的思路:

  1. 首先把能获取到的构造方法都拿出来,如果构造方法只有一个,且目前也没有任何和构造方法有关的参数,那就直接用这个构造方法就行了 。
  2. 如果第一步不能解决问题,接下来就遍历所有的构造方法,并且和已有的参数进行参数数量和类型比对,找到合适的构造方法并调用 。
2.5 PreferredConstructors继续回到一开始的源码中,接下来是这样了:
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容器原始Bean是如何创建的?

文章插图
其实看 Spring 源码,松哥最大的感悟就是小伙伴们一定要了解 Spring 的各种用法,在此基础之上,源码就很好懂,如果你只会 Spring 一些基本用法,那么源码一定是看得云里雾里的 。
END




推荐阅读