上一篇文章写到了被@Bean注解的方法如何转变成beanDef,进入bdMap的
现在继续来跟进beanDef是如何转变成为真正的SpringBean的
先上一段Spring源码阅读经典代码
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh(); // springboot依赖starter-web后,里会进入AbstractApplicationContext子类AnnotationConfigServletWebServerApplicationContext里的onRefresh(),进而启动web容器
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 这里会生成SpringBean对象,跟进去看即可
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
。。。
从bdMap里拿到需要被制作成SpringBean的beanDef
上面12个方法的第11个,也就是倒数第二个finishBeanFactoryInitialization(beanFactory);
方法里,会将beanFactory中的bdMap里的beanDef拿出来实例化,包装,然后放到单利池singletonObjects
中。
从该方法的最后一个调用继续跟进去
preInstantiateSingletons
该方法很简单
- 首先拿到beanNames列表,
- 然后循环实例化每个class,
- 通过getBean(beanName)继续进行实例化流程
getBean(beanName)是个空壳方法,继续调用doGetBean(name, requiredType, args, false);
。
doGetBean
doGetBean
方法里会进行beanName的转换,循环引用的判断与处理,创建单例bean。这里314行通过
getSingleton(String beanName, ObjectFactory<?> singletonFactory)
方法进入,内部再回调lambda表达式里的createBean()
方法,完成其后续操作。实际上,创建lambda中高的beanBean(beanName, mbd, args)
方法就是真正来创建SpringBean的。PS:
AbstractBeanFactory
是DefaultSingletonBeanRegistry
的子类那么就直接看
createBean()
吧。getSingleton
这里传递的singletonFactory是AbstractAutowireCapableBeanFactory,所以,246行的getObject()也就进入下面的截图了
createBean
可以看到mbdToUse的属性,大多都是上一篇文章里写的class进入bdMap里面的内容。
doCreateBean
doCreateBean方法里,首先create一个beanInstanceWrapper,这是个BeanWrapper对象,也就是说,先把需要处理的class整成一个包装对象instanceWrapper。
进入createBeanInstance继续看
createBeanInstance
生成class的对象
注意了,在此之前的所有操作,对于@Component,@Service,@Bean是没有区别的,区别从这里开始,因为@Bean注解的方法生成的beanDef,也就是截图里的mbd里的factoryMethodName是有值的。所以会通过instantiateUsingFactoryMethod(beanName, mbd, args)
方法来创建 包装对象。
接下来进入该方法
没什么可说的,继续往下跟踪
instantiateUsingFactoryMethod
很简单的代码,拿到factoryBeanName,拿到factoryBean,判断factoryBean是否被代理过,如果被代理过,就去拿代理前的对象。箭头指的代码如下
public static Class<?> getUserClass(Class<?> clazz) {
if (clazz.getName().contains(CGLIB_CLASS_SEPARATOR)) {
Class<?> superclass = clazz.getSuperclass();
if (superclass != null && superclass != Object.class) {
return superclass;
}
}
return clazz;
}
为什么要那代理前的对象呢?因为474行,需要通过代理前的类获取候选方法。
只有一个方法xyz()能够进入候选方法列表里,然后调用
instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS)
。注意:这里的factoryBean用的可是代理对象哦。image.png
这个
CglibSubclassingInstantiationStrategy
是怎么来的呢?其实是事先定义好的。
cglib_instance.gif
跟踪进入后面的
instantiate( mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args)
方法里image.png
很简单的来个反射调用,执行xyz()方法里的代码,拿到返回值。
invoke.gif
可以看到调用xyz()方法是,在返回实例之前可以执行其他代码。
result
区别至此结束,@Bean要生成的的对象搞出来了,下面就是如何生成SpringBean了。
下面的内容与@Component,@Service等已基本无差别。属于将class的对象制作成SpringBean的内容
上面代码一路返回,来到这里
wrapper
image.png
得到了包装类型了吧。接着往下来到了非常重要的属性填充环节。
image.png
populateBean()
applyPropertyValues()
这里的pvs,也就是PropertyValues是空,就直接返回了,不是重点。
属性填充完毕后,就是初始化bean了
initializeBean
initializeBean()
initializeBean里会调用setXXX()注入的方法,调用后置处理器,调用生命周期重的初始化回调方法,调用后置处理器的postProcessAfterInitialization()方法然后返回wrappedBean,赋值给exposedObject,并且返回exposedObject。
继续返回
继续返回
image.png 继续返回
这里返回到了getSingletion()里,拿到了SpringBean,然后在282行
addSingleton(beanName, singletonObject);
里,将其注入到ioc容器addSingleton
网友评论