上回讲到如何通过getBean方法来获取bean,这里感觉流程比较复杂,不知道以我的水平是否能讲清楚,如果有不清楚的地方欢迎讨论
Engine engine = (Engine)beanFactory.getBean("engine");
OK,不多废话追寻源码,这时候会遇到第一个问题XmlBeanFactory中没有getBean(String str)方法,经过查找在其父类AbstractBeanFactory中,
这里有两层逻辑,主要逻辑是首先检查bean是否初始化过,如果是则从以后的信息中获取;如果不是则从bean注册的信息中找到bean 对应的 BeanDefinition,然后创建新的bean
下面我先分析一下普通bean的初始化
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
......
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
......
if (!typeCheckOnly) {
//标记一下这个bean被创建过
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
......
//查看这个bean是否跟其他bean有依赖关系
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
......
//注册依赖bean
registerDependentBean(dependsOnBean, beanName);
getBean(dependsOnBean);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory
咱们重点来看一下spring是如何穿件单例bean的,也就是createBean(beanName, mbd, args)方法,该方法在AbstractAutowireCapableBeanFactory中实现,在该类中关键的地方是
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
明显能看到,这里就是创建实例的地方,咱们接着进去看看
这里先看我标注的这行,这个方法是创建一个bean实例并返回一个BeanWrapper对象,那BeanWrapper又是什么呢?接着往下看
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
.....
return instantiateBean(beanName, mbd);
}
这里能看到BeanWrapper其实是对bean的一个包装,看BeanWrapper的代码的话会发现里面包含bean的各种信息.
注意:BeanWrapper这个类很重要,bean初始化之后,对bean属性的编辑(即对属性赋值)都是通过BeanWrapper完成的
咱们接着看实例化bean的过程
这里主要有三部操作,首先获取class信息,然后通过class信息获取构造器,最后通过构造器创建bean实例
注意:看通过class获取构造器这里,就是这里要求bean必须要有无参构造函数
OK,到这里一个简单的spring管理bean的流程就走完了,现在咱们再来总结一下spring管理的流程
1、读取配置文件信息
2、解析配置文件信息,并把bean节点信息(包括bean的关联关系)保存在BeanDefinition中
3、把读取过的bean信息在BeanFactory中注册
4、调getBean时创建对象实例(懒加载)——通过beanName从BeanFactory中获取BeanDefinition得到bean信息,然后获取构造器创建bean实例
当然,这只是最简单的一个流程,还有很多问题是我没提到的,比如:这里是如何保证单例的?有依赖关系的Bean是如何初始化的?非延迟加载时在什么时候进行初始化的?等等,想知道这些那咱们接着一起往下探讨吧
这里应该有一个类图用来描述spring核心类的依赖关系,但我太懒.有兴趣的同学可以去网上搜一下,反正类图都是一样的