- 容器基本用法
测试类
XML文件
测试代码
测试类第一行代码调用了默认标签的解析及BeanDifition加载的逻辑。
测试类的第二行代码则开始了加载bean的逻辑。
- 源码学习
直接进入getBean方法,定义在BeanFactory接口中,有很多重载,看AbstractBeanFactory中的实现:
调用了doGetBean方法,doGetBean的代码量很大,逻辑也相对复杂:
首先,通过transformedBeanName方法获取对应的beanName,因为传入的name可能是别名,可能是beanName等。这个方法的详细逻辑就略过了。
获取对应的beanName之后,进入getSingleton方法,这个方法的实现在DefaultSingletonBeanRegistry类中:
这段代码存在循环依赖的检测以及多处bean的缓存,首先从singletonObjects中获取,获取不到且当前单例正在创建中则从earlySingletonObjects中获取,如果还是获取不到且allowEarlyReference,则尝试获取ObjectFactory,调用其getObject方法。最后无论是否获取到都返回。回到doGetBean方法,如果获取到单例且传入的args为null,则直接调用getObjectForBeanInstance方法:
这段代码主要是对name不是以&为前缀且beanInstance是FactoryBean的实例进行处理,而这个逻辑主要由FactoryBeanRegistrySupport类的getObjectFromFactoryBean方法处理:
上面的代码主要是一些逻辑的处理,但是没有真正的获取bean,保证了单例的全局唯一性,以及非单例模式的创建。接下来进入doGetObjectFromFactoryBean方法:
//这个代码的逻辑比较简单,首先是判断需不需要权限,不论是否需要权限都会调factoryBean的getObject()方法,最后是对返回值为null的情况做处理,最后返回object。接下来回到getObjectFromFactoryBean方法,可以看到除了逻辑处理之外,对于单例和非单例的创建都调用了postProcessObjectFromFactoryBean方法:
这里的实现是直接返回object,但是在其子类AbstractAutowireCapableBeanFactory有对postProcessObjectFromFactoryBean的重写:
从代码来看就是对结果的处理,后处理器目前并没有接触或者使用,以后了解了再补充。接下来根据return一步一步返回上一层,回到getObjectFromFactoryBean方法,不论是哪种情况,都会在调用了postProcessObjectFromFactoryBean后进行返回。回到getObjectForBeanInstance方法,其实是根据传入的beanName和实例是否是FactoryBean类型的实例对实例进行处理。再回到doGetBean方法,接下来就是对sharedInstance为null或者args不为null两种情况的处理。跳过parentBeanFactory中获取bean的过程,直接看后面的程序,如果不仅仅是做类型检查的话,需要调用markBeanAsCreated方法对缓存进行维护:
首先isDependent以及registerDependentBean方法主要是对循环依赖的维护以及检测。for循环中主要是获取依赖的bean,主要还是调用getBean方法。将所有的依赖bean都创建完成之后才会开始当前bean的创建。首先是单例模式的创建:
首先是调用了getSingleton方法传入beanName并且使用lambda表达式传入了一段代码,最后将返回值赋值给sharedInstance。在低版本中也可能是实例化一个接口并实现接口中的方法。
首先看getSingleton方法,在DefaultSingletonBeanRegistry类中实现,有两种重载,看当前调用的这个:
beforeSingletonCreation和afterSingletonCreation两个方法是对缓存的维护,还有对发生异常以及创建完后之后的缓存等逻辑,而真正的bean创建则在singletonFactory实例的getObject()方法,这里可以看到其实指正的代码调用其实是通过lambda表达式传入的代码。
进createBean方法,在AbstractBeanFactory类中是一个抽象方法,在其子类AbstractAutowireCapableBeanFactory中实现:
直接看prepareMethodOverrides方法,在AbstractBeanDefinition类中实现:
在定义bean的时候有两个属性,lookup-method和replace-method,这里做了部分匹配工作以及方法的存在性验证,对于重载方法还需要参数类型验证,这里并没有完成。
接下来进入真正的创建bean的代码doCreateBean方法:
先进入createBeanInstance方法:
autowireConstructor方法代码量非常大,但是总体来说做了两件事,确定构造函数,调用实例化策略的instantiateBean方法创建实例并加入到BeanWrapper中。而instantiateBean同样也是调用了实例化策略的instantiateBean方法:
首先看实例化策略,也就是getInstantiationStrategy方法,在AbstractAutowireCapableBeanFactory类中:
显而意见,如果用户不去设置,则默认的就是CglibSubclassingInstantiationStrategy类的实例,而CglibSubclassingInstantiationStrategy则是SimpleInstantiationStrategy类的子类,instantiate也是在SimpleInstantiationStrategy类中实现的:
反射的具体过程这里就不看了,直接进入CglibSubclassingInstantiationStrategy类重写的instantiateWithMethodInjection方法:
终于完成了实例的创建,可以返回doCreateBean函数了。当bean创建完毕之后,需要进行属性填充以及调用初始化方法,当然也可能没有,初始化方法中也存在一些其他逻辑,最后则是收尾工作,检测依赖以及注册需要销毁的bean,就不再进入代码详细分析了。doCreateBean方法结束后其实一直返回会发现关于bean的创建基本上已经结束了,其他的逻辑比较简单。至此关于bean的创建告一段落。
如果有不正确的地方欢迎指正。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/55685.html