java-spring 06 图灵 doGetBean方法

news/2024/10/20 3:49:00/

01.getBean() -> doGetBean() -> createBean() -> doCreateBean() -> createBeanInstance() -> populateBean() -> initializeBean() 流程

	@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)throws BeansException {/*** 提取对应的beanName,有人可能会认为此处直接使用即可,为什么还要进行转换呢,原因在于当bean对象实现FactoryBean接口之后就会变成&beanName,同时如果存在别名,也需要把别名进行转换*/String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons./**提前检查单例缓存中是否有手动注册的单例对象,跟循环依赖有关联*/Object sharedInstance = getSingleton(beanName);// 如果bean的单例对象找到了,且没有创建bean实例时要使用的参数if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}// 返回对象的实例,这句话的重点在于当你实现了FactoryBean接口的对象,需要获取具体的对象的时候就需要此方法来进行获取了bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.// 当对象都是单例的时候会尝试解决循环依赖的问题,但是原型模式下如果存在循环依赖的情况,那么直接抛出异常if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.// 如果bean定义不存在,就检查父工厂是否有BeanFactory parentBeanFactory = getParentBeanFactory();// 如果beanDefinitionMap中也就是在所有已经加载的类中不包含beanName,那么就尝试从父容器中获取if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.// 获取name对应的规范名称【全类名】,如果name前面有'&',则会返回'&'+规范名称【全类名】String nameToLookup = originalBeanName(name);// 如果父工厂是AbstractBeanFactory的实例if (parentBeanFactory instanceof AbstractBeanFactory) {// 调用父工厂的doGetBean方法,就是该方法。【递归】return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.// 如果有创建bean实例时要使用的参数// Delegation to parent with explicit args. 使用显示参数委派给父工厂// 使用父工厂获取该bean对象,通bean全类名和创建bean实例时要使用的参数return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.// 没有创建bean实例时要使用的参数 -> 委托给标准的getBean方法。// 使用父工厂获取该bean对象,通bean全类名和所需的bean类型return parentBeanFactory.getBean(nameToLookup, requiredType);}else {// 使用父工厂获取bean,通过bean全类名return (T) parentBeanFactory.getBean(nameToLookup);}}// 如果不是做类型检查,那么表示要创建bean,此处在集合中做一个记录if (!typeCheckOnly) {// 为beanName标记为已经创建(或将要创建)markBeanAsCreated(beanName);}try {// 此处做了BeanDefinition对象的转换,当我们从xml文件中加载beandefinition对象的时候,封装的对象是GenericBeanDefinition,// 此处要做类型转换,如果是子类bean的话,会合并父类的相关属性RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查mbd的合法性,不合格会引发验证异常checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.// 如果存在依赖的bean的话,那么则优先实例化依赖的beanString[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// 如果存在依赖,则需要递归实例化依赖的beanfor (String dep : dependsOn) {// 如果beanName已注册依赖于dependentBeanName的关系if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}// 注册各个bean的依赖关系,方便进行销毁registerDependentBean(dep, beanName);try {// 递归优先实例化被依赖的BeangetBean(dep);}// 捕捉为找到BeanDefinition异常:'beanName'依赖于缺少的bean'dep'catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.// 创建bean的实例对象if (mbd.isSingleton()) {// 返回以beanName的(原始)单例对象,如果尚未注册,则使用singletonFactory创建并注册一个对象:sharedInstance = getSingleton(beanName, () -> {try {// 为给定的合并后BeanDefinition(和参数)创建一个bean实例return createBean(beanName, mbd, args);}catch (BeansException ex) {// Explicitly remove instance from singleton cache: It might have been put there// eagerly by the creation process, to allow for circular reference resolution.// Also remove any beans that received a temporary reference to the bean.// 显示地从单例缓存中删除实例:它可能是由创建过程急切地放在那里,以允许循环引用解析。还要删除// 接收到该Bean临时引用的任何Bean// 销毁给定的bean。如果找到相应的一次性Bean实例,则委托给destoryBeandestroySingleton(beanName);// 重新抛出exthrow ex;}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}// 原型模式的bean对象创建else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.// 它是一个原型 -> 创建一个新实例// 定义prototype实例Object prototypeInstance = null;try {// 创建Prototype对象前的准备工作,默认实现将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);// 为mbd(和参数)创建一个bean实例prototypeInstance = createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}else {// 指定的scope上实例化beanString scopeName = mbd.getScope();if (!StringUtils.hasLength(scopeName)) {throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'");}// 从scopes中获取scopeName对于的Scope对象Scope scope = this.scopes.get(scopeName);// 如果scope为nullif (scope == null) {// 抛出非法状态异常:没有名为'scopeName'的scope注册throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {// 从scope中获取beanName对应的实例对象Object scopedInstance = scope.get(beanName, () -> {// 创建Prototype对象前的准备工作,默认实现 将beanName添加到prototypesCurrentlyInCreation中beforePrototypeCreation(beanName);try {// 为mbd(和参数)创建一个bean实例return createBean(beanName, mbd, args);}finally {// 创建完prototype实例后的回调,默认是将beanName从prototypesCurrentlyInCreation移除afterPrototypeCreation(beanName);}});// 从beanInstance中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是// FactoryBean会直接返回beanInstance实例bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {// 捕捉非法状态异常// 抛出Bean创建异常:作用域 'scopeName' 对于当前线程是不活动的;如果您打算从单个实例引用它,请考虑为此// beanDefinition一个作用域代理throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {// 捕捉获取Bean对象抛出的Bean异常// 在Bean创建失败后,对缓存的元数据执行适当的清理cleanupAfterBeanCreationFailure(beanName);// 重新抛出exthrow ex;}}// Check if required type matches the type of the actual bean instance.// 检查requiredType是否与实际Bean实例的类型匹配// 如果requiredType不为null&&bean不是requiredType的实例if (requiredType != null && !requiredType.isInstance(bean)) {try {// 获取此BeanFactory使用的类型转换器,将bean转换为requiredTypeT convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);// 如果convertedBean为nullif (convertedBean == null) {// 抛出Bean不是必要类型的异常throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}// 返回convertedBeanreturn convertedBean;}catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {logger.trace("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}// 将bean返回出去return (T) bean;}

03.这一段

	// name有可能是 &xxx 或者 xxx,如果name是&xxx,那么beanName就是xxx// name有可能传入进来的是别名,那么beanName就是idString beanName = transformedBeanName(name);Object beanInstance;// Eagerly check singleton cache for manually registered singletons.Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}// 如果sharedInstance是FactoryBean,那么就调用getObject()返回对象beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);}

04.这一段:

	private final Map<String, Scope> scopes = new LinkedHashMap<>(8);
	protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// Don't let calling code try to dereference the factory if the bean isn't a factory.// 如果&xxx,那么就直接返回单例池中的对象if (BeanFactoryUtils.isFactoryDereference(name)) {if (beanInstance instanceof NullBean) {return beanInstance;}if (!(beanInstance instanceof FactoryBean)) {throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());}if (mbd != null) {mbd.isFactoryBean = true;}return beanInstance;}// Now we have the bean instance, which may be a normal bean or a FactoryBean.// If it's a FactoryBean, we use it to create a bean instance, unless the// caller actually wants a reference to the factory.// 单例池中的对象不是FactoryBean,则直接返回if (!(beanInstance instanceof FactoryBean)) {return beanInstance;}Object object = null;if (mbd != null) {mbd.isFactoryBean = true;}else {// 从factoryBeanObjectCache中直接拿对象object = getCachedObjectForFactoryBean(beanName);}if (object == null) {// Return bean instance from factory.FactoryBean<?> factory = (FactoryBean<?>) beanInstance;// Caches object obtained from FactoryBean if it is a singleton.if (mbd == null && containsBeanDefinition(beanName)) {mbd = getMergedLocalBeanDefinition(beanName);}// synthetic为true,表示这个Bean不是正常的一个Bean,可能只是起到辅助作用的,所以这种Bean就不用去执行PostProcessor了boolean synthetic = (mbd != null && mbd.isSynthetic());object = getObjectFromFactoryBean(factory, beanName, !synthetic);}return object;}

http://www.ppmy.cn/news/1428176.html

相关文章

【IoTDB 线上小课 02】开源增益的大厂研发岗面经

还有友友不知道我们的【IoTDB 视频小课】系列吗&#xff1f; 关于 IoTDB&#xff0c;关于物联网&#xff0c;关于时序数据库&#xff0c;关于开源...给我们 5 分钟&#xff0c;持续学习&#xff0c;干货满满~ 5分钟学会 大厂研发岗面试 之前的第一期小课&#xff0c;我们听了 I…

科目一笔记

扣分 目前只有 12 9 6 3 1分。 扣1分的 会车 不按照规定会车&#xff0c; 普倒掉&#xff08;普通路上不按规定掉头&#xff0c;倒车&#xff09; ​ 高速、城市快速路…以外的道路 普通路 ​ 校车…以外的道车 普通车 使用灯光 ​ 需要注意的是只有不按规定使用灯光&…

【AR开发示例】实现AR管线巡检

写在前面的话 这是一篇旧文档&#xff0c;代码仓库见 https://gitee.com/tanyunxiu/AR-pipe 本文档是基于超图移动端SDK的AR模块开发的示例&#xff0c;仅供参考&#xff0c;SDK在持续迭代中&#xff0c;相关描述可能有变化。 示例介绍 这是一个使用AR查看墙内管线的基础示…

stack queue Leetcode 栈和队列算法题

232.用栈实现队列 Queue 是 Collection 接口下的&#xff0c;她的一个实现类是ArrayDeque. 不推荐使用 Vector 实现的 Stack&#xff0c;因为为了保证线程安全使得 Stack 的效率很低&#xff0c;而且由于继承的 Vector 导致没有屏蔽一些栈不应该有的操作 stack 下使用入栈出…

机器人路径规划:基于Q-learning算法的移动机器人路径规划,可以自定义地图,修改起始点,提供MATLAB代码

一、Q-learning算法 Q-learning算法是强化学习算法中的一种&#xff0c;该算法主要包含&#xff1a;Agent、状态、动作、环境、回报和惩罚。Q-learning算法通过机器人与环境不断地交换信息&#xff0c;来实现自我学习。Q-learning算法中的Q表是机器人与环境交互后的结果&#…

STL的map:ALV树和红黑树

ALV树 平衡因子的几种情况 单旋 双旋 红黑树 三种情况 第二种情况变种&#xff1a;不同的是折线要双旋 总结&#xff1a;

如何批量给Word文件增加前缀序号?“汇帮批量重命名”帮助你批量给word文件增加前缀序号。

批量给Word文件增加前缀序号的过程&#xff0c;对于经常处理大量文档的人来说&#xff0c;是一项既繁琐又必要的任务。首先&#xff0c;我们需要明确为什么要给Word文件增加前缀序号。在很多情况下&#xff0c;当我们需要按照一定的顺序对多个文档进行管理和归档时&#xff0c;…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之二 简单人脸检测添加戴眼镜效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之二 简单人脸检测添加戴眼镜效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单人脸检测/识别实战案例 之二 简单人脸检测添加戴眼镜效果 一、简单介绍 二、简单人脸检测添加戴眼镜效…