【细读Spring Boot源码】Spring如何获取一个Bean?BeanFactory的getBean方法

news2024/10/5 13:50:24

前言

在读refresh(context);时,finishBeanFactoryInitialization(beanFactory);beanFactory.preInstantiateSingletons();用于实例化剩余所有的non-lazy-init的单例。这里包含了前置处理器和后置处理器
这里面就用到了本文主题getBean(beanName);
在这里插入图片描述
下面具体看看这个方法的源码

类图

在这里插入图片描述
AbstractBeanFactory实现了BeanFactory中getBean(String name)

调用主流程

public Object getBean(String name) throws BeansException {
	// 找到做事的方法doGetBean
	return doGetBean(name, null, null, false);
}

解析做事的主方法doGetBean

protected <T> T doGetBean(
		String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {
	
	// 转换bean为实际的名称
	String beanName = transformedBeanName(name);
	// 保存Bean实例的对象
	Object beanInstance;

	// Eagerly check singleton cache for manually registered singletons.
	// 检查单例缓存是否有手动注册的单例,这里涉及到三级缓存
	// 看详解1
	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 + "'");
			}
		}
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		// Fail if we're already creating this bean instance:
		// We're assumably within a circular reference.
		// 如果我们已经在创建这个bean实例,则失败: 我们假设在循环引用中
		if (isPrototypeCurrentlyInCreation(beanName)) {
			throw new BeanCurrentlyInCreationException(beanName);
		}

		// Check if bean definition exists in this factory.
		// 检查此工厂中是否存在bean定义
		// 获取父Bean工厂
		BeanFactory parentBeanFactory = getParentBeanFactory();
		// 从beanDefinitionMap里containsKey一下这个beanName ,不在则进入此条件
		if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
			// Not found -> check parent.
			// 不在检查其父
			String nameToLookup = originalBeanName(name);
			if (parentBeanFactory instanceof AbstractBeanFactory) {
				return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
						nameToLookup, requiredType, args, typeCheckOnly);
			}
			else if (args != null) {
				// Delegation to parent with explicit args.
				return (T) parentBeanFactory.getBean(nameToLookup, args);
			}
			else if (requiredType != null) {
				// No args -> delegate to standard getBean method.
				return parentBeanFactory.getBean(nameToLookup, requiredType);
			}
			else {
				return (T) parentBeanFactory.getBean(nameToLookup);
			}
		}

		// 类型检查是否获取实例不用于实际使用
		if (!typeCheckOnly) {
			// 将指定的bean标记为已创建 (或即将创建)
			markBeanAsCreated(beanName);
		}

		StartupStep beanCreation = this.applicationStartup.start("spring.beans.instantiate")
				.tag("beanName", name);
		try {
			if (requiredType != null) {
				beanCreation.tag("beanType", requiredType::toString);
			}
			// 获取合并后的BeanDefinition,详见详解2
			RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
			// 检查是否是抽象的,是抽象的报错
			checkMergedBeanDefinition(mbd, beanName, args);

			// Guarantee initialization of beans that the current bean depends on.
			// 获取DependsOn
			String[] dependsOn = mbd.getDependsOn();
			// 有依赖的,要先初始化依赖的
			if (dependsOn != null) {
				// 循环处理依赖
				for (String dep : dependsOn) {
					// 判断是否已经依赖,循环依赖
					if (isDependent(beanName, dep)) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
					}
					// 注册依赖Bean
					registerDependentBean(dep, beanName);
					try {
						// 先获取依赖的Bean
						getBean(dep);
					}
					catch (NoSuchBeanDefinitionException ex) {
						throw new BeanCreationException(mbd.getResourceDescription(), beanName,
								"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
					}
				}
			}

			// Create bean instance.
			// 是否是单例的,创建Bean实例
			if (mbd.isSingleton()) {
				// 这里是个回调函数,先进入看getSingleton方法,看详解3
				sharedInstance = getSingleton(beanName, () -> {
					try {
						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.
						destroySingleton(beanName);
						throw ex;
					}
				});
				beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
			}

			else if (mbd.isPrototype()) {
				// It's a prototype -> create a new instance.
				Object prototypeInstance = null;
				try {
					beforePrototypeCreation(beanName);
					prototypeInstance = createBean(beanName, mbd, args);
				}
				finally {
					afterPrototypeCreation(beanName);
				}
				beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
			}

			else {
				String scopeName = mbd.getScope();
				if (!StringUtils.hasLength(scopeName)) {
					throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
				}
				Scope scope = this.scopes.get(scopeName);
				if (scope == null) {
					throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
				}
				try {
					Object scopedInstance = scope.get(beanName, () -> {
						beforePrototypeCreation(beanName);
						try {
							return createBean(beanName, mbd, args);
						}
						finally {
							afterPrototypeCreation(beanName);
						}
					});
					beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
				}
				catch (IllegalStateException ex) {
					throw new ScopeNotActiveException(beanName, scopeName, ex);
				}
			}
		}
		catch (BeansException ex) {
			beanCreation.tag("exception", ex.getClass().toString());
			beanCreation.tag("message", String.valueOf(ex.getMessage()));
			cleanupAfterBeanCreationFailure(beanName);
			throw ex;
		}
		finally {
			beanCreation.end();
		}
	}

	// 适配Bean实例。详看6
	return adaptBeanInstance(name, beanInstance, requiredType);
}

详解1——Object sharedInstance = getSingleton(beanName);

public Object getSingleton(String beanName) {
	// allowEarlyReference(应该创建早期引用)属性为true
	return getSingleton(beanName, true);
}

检查已经实例化的单例,并且还允许对当前创建的单例进行早期引用 (解析循环引用)。
三级缓存:

  • singletonObjects:单例对象的缓存
  • earlySingletonObjects:早期单例对象的缓存
  • singletonFactories:单例工厂的缓存
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	// 取单例,取到直接返回
	Object singletonObject = this.singletonObjects.get(beanName);
	// 没取到 且 正在创建
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		// 从早期单例对象取,取到直接返回
		singletonObject = this.earlySingletonObjects.get(beanName);
		// 没取到 且 需要创建早期引用
		if (singletonObject == null && allowEarlyReference) {
			// 加锁
			synchronized (this.singletonObjects) {
				// Consistent creation of early reference within full singleton lock
				// 在加锁的情况下再次取单例,确定在这个过程中是否已经创建完成。取到直接返回
				singletonObject = this.singletonObjects.get(beanName);
				// 未取到
				if (singletonObject == null) {
					// 在加锁的情况下再次取早期单例,确定在这个过程中是否已创建早期单例对象。取到直接返回
					singletonObject = this.earlySingletonObjects.get(beanName);
					// 未取到
					if (singletonObject == null) {
						// 去单例工厂。未取到返回null
						ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
						// 取到单例工厂
						if (singletonFactory != null) {
							// 创建一个单例对象
							singletonObject = singletonFactory.getObject();
							// 放入早期单例对象
							this.earlySingletonObjects.put(beanName, singletonObject);
							// 从工厂中移除
							this.singletonFactories.remove(beanName);
						}
					}
				}
			}
		}
	}
	// 有4中情况的返回 单例对象、早期单例对象、单例工厂、null
	return singletonObject;
}

详看2——getObjectForBeanInstance(sharedInstance, name, beanName, null);

protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// 当前创建的Bean
	String currentlyCreatedBean = this.currentlyCreatedBean.get();
	// 不为空
	if (currentlyCreatedBean != null) {
		// 为给定的bean注册一个依赖的bean,在给定的bean被销毁之前要销毁
		registerDependentBean(beanName, currentlyCreatedBean);
	}

	// 调用父类的方法
	return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}

父类AbstractBeanFactorygetObjectForBeanInstance方法

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.
	// 如果bean不是工厂,请不要让调用代码尝试取消引用工厂。
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		if (beanInstance instanceof NullBean) {
			return beanInstance;
		}
		if (!(beanInstance instanceof FactoryBean)) {
			throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
		}
		// 把isFactoryBean属性置为true
		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.
	// 现在我们有一个Bean的实例,可能是普通Bean也可能是工厂Bean
	// 如果他是一个FactoryBean,我们用它创建一个Bean实例,除非调用者想要一个工厂的引用
	if (!(beanInstance instanceof FactoryBean)) {
		// 不是工厂Bean直接返回实例对象 
		return beanInstance;
	}

	Object object = null;
	if (mbd != null) {
		mbd.isFactoryBean = true;
	}
	else {
		// 从缓存里取
		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);
		}
		boolean synthetic = (mbd != null && mbd.isSynthetic());
		// 通过工厂Bean创建一个Bean
		object = getObjectFromFactoryBean(factory, beanName, !synthetic);
	}
	return object;
}

详解3——RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
	// Quick check on the concurrent map first, with minimal locking.
	// 在 concurrent map上快速检查,锁定最少
	RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
	if (mbd != null && !mbd.stale) {
		return mbd;
	}
	// 没有再去调用获取。getBeanDefinition是在beanDefinitionMap里取。
	return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));
}
protected RootBeanDefinition getMergedBeanDefinition(String beanName, BeanDefinition bd)
		throws BeanDefinitionStoreException {
	// 再去调用获取
	return getMergedBeanDefinition(beanName, bd, null);
}

获取详情,作用:如果给定bean的定义是子bean定义,则通过与父级合并来返回给定bean的RootBeanDefinition。
参数:

  • beanName -bean定义的名称
  • bd -原始bean定义 (Root/ChildBeanDefinition)
  • containingBd -inner bean定义的包含bean定义,顶级bean定义的null
protected RootBeanDefinition getMergedBeanDefinition(
		String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd)
		throws BeanDefinitionStoreException {

	synchronized (this.mergedBeanDefinitions) {
		RootBeanDefinition mbd = null;
		RootBeanDefinition previous = null;

		// Check with full lock now in order to enforce the same merged instance.
		// 在锁下检测为了强制执行相同的合并实例
		if (containingBd == null) {
			mbd = this.mergedBeanDefinitions.get(beanName);
		}

		// 定义没取到合并后 或 定义需要重新合并
		if (mbd == null || mbd.stale) {
			// 保留mdb对象
			previous = mbd;
			// 取父定义的名称 为空
			if (bd.getParentName() == null) {
				// Use copy of given root bean definition.
				// 使用给定root bean 定义的拷贝
				if (bd instanceof RootBeanDefinition) {
					// 本身就是直接clone
					mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
				}
				else {
					// bd转为RootBeanDefinition
					mbd = new RootBeanDefinition(bd);
				}
			}
			// 有父定义的名称
			else {
				// Child bean definition: needs to be merged with parent.
				// 子定义需要merged给父定义
				BeanDefinition pbd;
				try {
					// 获取父BeanName
					String parentBeanName = transformedBeanName(bd.getParentName());
					// 与父名称不一样
					if (!beanName.equals(parentBeanName)) {
						// 合并
						pbd = getMergedBeanDefinition(parentBeanName);
					}
					else {
						// 得到父BeanFactory
						BeanFactory parent = getParentBeanFactory();
						if (parent instanceof ConfigurableBeanFactory) {
							// 从父BeanFactory得到BeanDefinition
							pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName);
						}
						else {
							throw new NoSuchBeanDefinitionException(parentBeanName,
									"Parent name '" + parentBeanName + "' is equal to bean name '" + beanName +
											"': cannot be resolved without a ConfigurableBeanFactory parent");
						}
					}
				}
				catch (NoSuchBeanDefinitionException ex) {
					throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName,
							"Could not resolve parent bean definition '" + bd.getParentName() + "'", ex);
				}
				// Deep copy with overridden values.
				// 深拷贝覆盖值
				mbd = new RootBeanDefinition(pbd);
				mbd.overrideFrom(bd);
			}

			// Set default singleton scope, if not configured before.
			// 设置默认单例范围 (如果之前未配置)。
			if (!StringUtils.hasLength(mbd.getScope())) {
				mbd.setScope(SCOPE_SINGLETON);
			}

			// A bean contained in a non-singleton bean cannot be a singleton itself.
			// Let's correct this on the fly here, since this might be the result of
			// parent-child merging for the outer bean, in which case the original inner bean
			// definition will not have inherited the merged outer bean's singleton status.
			if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) {
				mbd.setScope(containingBd.getScope());
			}

			// Cache the merged bean definition for the time being
			// (it might still get re-merged later on in order to pick up metadata changes)
			// 暂时缓存合并的bean定义 (以后可能仍会重新合并以获取元数据更改)
			if (containingBd == null && isCacheBeanMetadata()) {
				this.mergedBeanDefinitions.put(beanName, mbd);
			}
		}
		if (previous != null) {
			// 复制相关的合并Bean定义缓存
			copyRelevantMergedBeanDefinitionCaches(previous, mbd);
		}
		return mbd;
	}
}

详解4——getSingleton()

public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
	Assert.notNull(beanName, "Bean name must not be null");
	// 先上锁,锁singletonObjects对象
	synchronized (this.singletonObjects) {
		// 缓存里取一下
		Object singletonObject = this.singletonObjects.get(beanName);
		// 没取到
		if (singletonObject == null) {
			// 判断是否正在销毁,默认属性为false
			if (this.singletonsCurrentlyInDestruction) {
				throw new BeanCreationNotAllowedException(beanName,
						"Singleton bean creation not allowed while singletons of this factory are in destruction " +
						"(Do not request a bean from a BeanFactory in a destroy method implementation!)");
			}
			if (logger.isDebugEnabled()) {
				logger.debug("Creating shared instance of singleton bean '" + beanName + "'");
			}
			// 单例创建前回调
			// 判断beanName在不在当前在创建检查中排除的bean名称缓存中
			// 加入当前正在创建的bean的名称缓存
			// 上面两个有一个失败false则抛BeanCurrentlyInCreationException异常
			beforeSingletonCreation(beanName);
			boolean newSingleton = false;
			boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
			if (recordSuppressedExceptions) {
				this.suppressedExceptions = new LinkedHashSet<>();
			}
			try {
				// 这个singletonFactory就是回调函数,getObject()就是调用回调函数
				// 这里 getObject()返回是主流程中的return createBean(beanName, mbd, args);
				// 详见4.1
				singletonObject = singletonFactory.getObject();
				newSingleton = true;
			}
			catch (IllegalStateException ex) {
				// Has the singleton object implicitly appeared in the meantime ->
				// if yes, proceed with it since the exception indicates that state.
				singletonObject = this.singletonObjects.get(beanName);
				if (singletonObject == null) {
					throw ex;
				}
			}
			catch (BeanCreationException ex) {
				if (recordSuppressedExceptions) {
					for (Exception suppressedException : this.suppressedExceptions) {
						ex.addRelatedCause(suppressedException);
					}
				}
				throw ex;
			}
			finally {
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = null;
				}
				afterSingletonCreation(beanName);
			}
			if (newSingleton) {
				addSingleton(beanName, singletonObject);
			}
		}
		return singletonObject;
	}
}

详看4.1——createBean(beanName, mbd, args)

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
	throws BeanCreationException {

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	// 确保此时bean类已实际解析,并在无法存储在共享合并bean定义中的动态解析类的情况下克隆bean定义。
	// 解析Bean类,详见4.2
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	// 有解析到class 且 不是BeanClass 且 有BeanClassName
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	// 准备方法覆盖
	try {
		// 检查查找方法是否存在,并确定其重载状态
		mbdToUse.prepareMethodOverrides();
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		// 给BeanPostProcessors一个返回代理而不是目标bean实例的机会。详看4.3
		Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
		if (bean != null) {
			return bean;
		}
	}
	catch (Throwable ex) {
		throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
				"BeanPostProcessor before instantiation of bean failed", ex);
	}

	try {
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	}
	catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}

详看4.2——resolveBeanClass(mbd, beanName);

解析Bean类

protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
		throws CannotLoadBeanClassException {

	try {
		// 是否存在Bean类
		if (mbd.hasBeanClass()) {
			// 直接返回
			return mbd.getBeanClass();
		}
		// 有安全策略
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
					() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
		}
		else {
			// 做解析Bean类操作
			return doResolveBeanClass(mbd, typesToMatch);
		}
	}
	catch (PrivilegedActionException pae) {
		ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
	}
	catch (ClassNotFoundException ex) {
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
	}
	catch (LinkageError err) {
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
	}
}

做解析动作

private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
		throws ClassNotFoundException {
	
	// 获取类加载器
	ClassLoader beanClassLoader = getBeanClassLoader();
	// 动态类加载器
	ClassLoader dynamicLoader = beanClassLoader;
	// 新的解析标志
	boolean freshResolve = false;

	// 处理类型匹配
	if (!ObjectUtils.isEmpty(typesToMatch)) {
		// When just doing type checks (i.e. not creating an actual instance yet),
		// use the specified temporary class loader (e.g. in a weaving scenario).
		ClassLoader tempClassLoader = getTempClassLoader();
		if (tempClassLoader != null) {
			dynamicLoader = tempClassLoader;
			freshResolve = true;
			if (tempClassLoader instanceof DecoratingClassLoader) {
				DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
				for (Class<?> typeToMatch : typesToMatch) {
					dcl.excludeClass(typeToMatch.getName());
				}
			}
		}
	}

	// 获取类全名
	String className = mbd.getBeanClassName();
	if (className != null) {
		// 评估bean定义中包含的给定字符串,有可能将其解析为表达式
		Object evaluated = evaluateBeanDefinitionString(className, mbd);
		// 是否是类全名
		if (!className.equals(evaluated)) {
			// A dynamically resolved expression, supported as of 4.2...
			// 一个动态解析的表达式
			if (evaluated instanceof Class) {
				return (Class<?>) evaluated;
			}
			else if (evaluated instanceof String) {
				className = (String) evaluated;
				freshResolve = true;
			}
			else {
				throw new IllegalStateException("Invalid class name expression result: " + evaluated);
			}
		}
		// 是一个新的解析
		if (freshResolve) {
			// When resolving against a temporary class loader, exit early in order
			// to avoid storing the resolved Class in the bean definition.
			if (dynamicLoader != null) {
				try {
					// 使用动态的类加载器加载类
					return dynamicLoader.loadClass(className);
				}
				catch (ClassNotFoundException ex) {
					if (logger.isTraceEnabled()) {
						logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
					}
				}
			}
			// 反射出类
			return ClassUtils.forName(className, dynamicLoader);
		}
	}

	// Resolve regularly, caching the result in the BeanDefinition...
	// 解析,将结果缓存在BeanDefinition中,看下面
	return mbd.resolveBeanClass(beanClassLoader);
}

mbd.resolveBeanClass(beanClassLoader);解析

public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
	// 得到类名
	String className = getBeanClassName();
	if (className == null) {
		return null;
	}
	// 详看4.3 获取类
	Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
	this.beanClass = resolvedClass;
	return resolvedClass;
}

获取类

public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
		throws ClassNotFoundException, LinkageError {

	Assert.notNull(name, "Name must not be null");

	// 解析原始类名,从primitiveTypeNameMap里取一下
	Class<?> clazz = resolvePrimitiveClassName(name);
	if (clazz == null) {
		// 从通用缓存里取一下
		clazz = commonClassCache.get(name);
	}
	if (clazz != null) {
		return clazz;
	}

	// "java.lang.String[]" style arrays
	// 一种数组风格
	if (name.endsWith(ARRAY_SUFFIX)) {
		String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
		Class<?> elementClass = forName(elementClassName, classLoader);
		return Array.newInstance(elementClass, 0).getClass();
	}

	// "[Ljava.lang.String;" style arrays
	// 一种数组风格
	if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
		String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
		Class<?> elementClass = forName(elementName, classLoader);
		return Array.newInstance(elementClass, 0).getClass();
	}

	// "[[I" or "[[Ljava.lang.String;" style arrays
	// 一种数组风格
	if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
		String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
		Class<?> elementClass = forName(elementName, classLoader);
		return Array.newInstance(elementClass, 0).getClass();
	}

	ClassLoader clToUse = classLoader;
	// 类加载器为空
	if (clToUse == null) {
		clToUse = getDefaultClassLoader();
	}
	try {
		// 反射出来实例
		return Class.forName(name, false, clToUse);
	}
	catch (ClassNotFoundException ex) {
		int lastDotIndex = name.lastIndexOf(PACKAGE_SEPARATOR);
		if (lastDotIndex != -1) {
			String nestedClassName =
					name.substring(0, lastDotIndex) + NESTED_CLASS_SEPARATOR + name.substring(lastDotIndex + 1);
			try {
				return Class.forName(nestedClassName, false, clToUse);
			}
			catch (ClassNotFoundException ex2) {
				// Swallow - let original exception get through
			}
		}
		throw ex;
	}
}

详看4.3——resolveBeforeInstantiation(beanName, mbdToUse)

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
	Object bean = null;
	// 没有在实例前解决
	if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
		// Make sure bean class is actually resolved at this point.
		// 确保bean类实际上在这一点上得到解决。
		if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
			// 确定目标类型
			Class<?> targetType = determineTargetType(beanName, mbd);
			if (targetType != null) {
				// 实例化前应用Bean Post处理器  重要 
				bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
				if (bean != null) {
					// 初始化后应用Bean Post处理器
					bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
				}
			}
		}
		mbd.beforeInstantiationResolved = (bean != null);
	}
	return bean;
}

实例化前应用Bean Post处理器,前置处理器

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
	for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
		Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
		if (result != null) {
			return result;
		}
	}
	return null;
}

初始化后应用Bean Post处理器

public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {

	Object result = existingBean;
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		Object current = processor.postProcessAfterInitialization(result, beanName);
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

详看5——doCreateBean(beanName, mbdToUse, args);

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	// Instantiate the bean.
	// 实例化一个bean
	BeanWrapper instanceWrapper = null;
	if (mbd.isSingleton()) {
		// 先从第三级缓存移除
		instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
	}
	if (instanceWrapper == null) {
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	}
	Object bean = instanceWrapper.getWrappedInstance();
	Class<?> beanType = instanceWrapper.getWrappedClass();
	if (beanType != NullBean.class) {
		mbd.resolvedTargetType = beanType;
	}

	// Allow post-processors to modify the merged bean definition.
	synchronized (mbd.postProcessingLock) {
		if (!mbd.postProcessed) {
			try {
				applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
			}
			catch (Throwable ex) {
				throw new BeanCreationException(mbd.getResourceDescription(), beanName,
						"Post-processing of merged bean definition failed", ex);
			}
			mbd.postProcessed = true;
		}
	}

	// Eagerly cache singletons to be able to resolve circular references
	// even when triggered by lifecycle interfaces like BeanFactoryAware.
	boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
			isSingletonCurrentlyInCreation(beanName));
	if (earlySingletonExposure) {
		if (logger.isTraceEnabled()) {
			logger.trace("Eagerly caching bean '" + beanName +
					"' to allow for resolving potential circular references");
		}
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
	}

	// Initialize the bean instance.
	Object exposedObject = bean;
	try {
		populateBean(beanName, mbd, instanceWrapper);
		exposedObject = initializeBean(beanName, exposedObject, mbd);
	}
	catch (Throwable ex) {
		if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
			throw (BeanCreationException) ex;
		}
		else {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
		}
	}

	if (earlySingletonExposure) {
		Object earlySingletonReference = getSingleton(beanName, false);
		if (earlySingletonReference != null) {
			if (exposedObject == bean) {
				exposedObject = earlySingletonReference;
			}
			else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
				String[] dependentBeans = getDependentBeans(beanName);
				Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
				for (String dependentBean : dependentBeans) {
					if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
						actualDependentBeans.add(dependentBean);
					}
				}
				if (!actualDependentBeans.isEmpty()) {
					throw new BeanCurrentlyInCreationException(beanName,
							"Bean with name '" + beanName + "' has been injected into other beans [" +
							StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
							"] in its raw version as part of a circular reference, but has eventually been " +
							"wrapped. This means that said other beans do not use the final version of the " +
							"bean. This is often the result of over-eager type matching - consider using " +
							"'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.");
				}
			}
		}
	}

	// Register bean as disposable.
	try {
		registerDisposableBeanIfNecessary(beanName, bean, mbd);
	}
	catch (BeanDefinitionValidationException ex) {
		throw new BeanCreationException(
				mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
	}

	return exposedObject;
}
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
	// Make sure bean class is actually resolved at this point.
	// 解析的bean类 (如果没有,则为null)
	Class<?> beanClass = resolveBeanClass(mbd, beanName);

	if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
		throw new BeanCreationException(mbd.getResourceDescription(), beanName,
				"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
	}
	
	// 获取实例供应商
	Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
	if (instanceSupplier != null) {
		return obtainFromSupplier(instanceSupplier, beanName);
	}

	// 获取factoryMethodName,不为空使用工厂方法实例化
	if (mbd.getFactoryMethodName() != null) {
		return instantiateUsingFactoryMethod(beanName, mbd, args);
	}

	// Shortcut when re-creating the same bean...
	// 重新创建相同bean时的快捷方式
	boolean resolved = false;
	boolean autowireNecessary = false;
	if (args == null) {
		synchronized (mbd.constructorArgumentLock) {
			if (mbd.resolvedConstructorOrFactoryMethod != null) {
				resolved = true;
				autowireNecessary = mbd.constructorArgumentsResolved;
			}
		}
	}
	if (resolved) {
		if (autowireNecessary) {
			return autowireConstructor(beanName, mbd, null, null);
		}
		else {
			return instantiateBean(beanName, mbd);
		}
	}

	// Candidate constructors for autowiring?
	Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
	if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
			mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
		return autowireConstructor(beanName, mbd, ctors, args);
	}

	// Preferred constructors for default construction?
	ctors = mbd.getPreferredConstructors();
	if (ctors != null) {
		return autowireConstructor(beanName, mbd, ctors, null);
	}

	// No special handling: simply use no-arg constructor.
	return instantiateBean(beanName, mbd);
}

详看6——adaptBeanInstance(name, beanInstance, requiredType);

适配Bean实例

<T> T adaptBeanInstance(String name, Object bean, @Nullable Class<?> requiredType) {
	// Check if required type matches the type of the actual bean instance.
	// 检查所需类型是否与实际bean实例的类型匹配。
	if (requiredType != null && !requiredType.isInstance(bean)) {
		try {
			// 类型转换器转换
			Object convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
			if (convertedBean == null) {
				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
			}
			return (T) 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());
		}
	}
	// 不需要转换
	return (T) bean;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/589556.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

4.数据结构期末复习之树

1.树的概念(一对多)(要求会写遍历序列) 1)n>个节点,n0时为空树2)仅有一个根节点3)左右节点互不相交,子节点一对多2.树的特点 1.子树之间没有关系 2.节点不属于多个子树(一个节点只能在一颗子树里面)3.没有回路(就是成环)4.有层次性3.术语 1.节点的度:拥有子树的个数…

ArcGIS教程——ArcGIS快速入门

实例数据&#xff1a;https://pan.baidu.com/s/184wwCmWrJdb-qjxsT614EQ 密码&#xff1a;dowv ArcGIS for Desktop是一套完整的专业GIS应用程序&#xff0c;包含有ArcMap、ArcCatalog、ArcToolbox、ArcScense、ArcGlobe和Model Builder等。其中ArcMap、ArcCatalog、ArcToolbo…

Unreal Niagara粒子入门3 - 根据模型顶点发射粒子

在一些游戏中经常会出现根据模型顶点位置发射粒子的情况&#xff0c;这次就来实现一下该效果&#xff1a; 1.基础创建操作 首先从空粒子发射器开始创建&#xff0c;右键NiagaraSystem->Create empty system&#xff0c;打开粒子系统后再右键Add empty emitter&#xff1a…

【智能软件安全】上海道宁为您带来智能软件安全平台——​Veracode,帮助您全面地保护您构建和管理地应用程序

Veracode可以全面地 保护您构建和管理地应用程序 在现代软件 开发生命周期的 每个阶段不断发现并修复缺陷 Veracode通过 建立一种在安全和开发团队之间 架起桥梁并授权 开发人员成为 安全倡导者的积极文化 从一开始就防止常见的安全漏洞 开发商介绍 Veracode成立于20…

腾讯云8核16G服务器18M带宽CPU性能可支撑多少人同时在线?

腾讯云8核16G轻量服务器CPU性能如何&#xff1f;18M带宽支持多少人在线&#xff1f;轻量应用服务器具有100%CPU性能&#xff0c;18M带宽下载速度2304KB/秒&#xff0c;折合2.25M/s&#xff0c;系统盘为270GB SSD盘&#xff0c;月流量3500GB&#xff0c;折合每天116.6GB流量&…

【CocosCreator入门】CocosCreator组件 | TiledMap(地图)组件

Cocos Creator是一款流行的游戏开发引擎&#xff0c;具有丰富的组件和工具&#xff0c;其中TiledMap组件可以帮助开发者快速创建、加载和渲染地图。 目录 一、组件介绍 二、组件属性 三、脚本控制 3.1加载地图 3.2渲染地图 四、详细说明 五、关闭裁剪 六、节点遮挡 一、…

Linux中与进程间通信相关的内核数据结构

【摘要】本文详细讲述了Linux内核中与进程间通信概念相关的内核数据结构及其内在联系。 九、进程间通信(IPC)相关数据结构 9.1 ipc_namespace 从内核版本2.6.19开始&#xff0c;IPC机制已经能够意识到命名空间的存在&#xff0c;但管理IPC命名空间比较简单&#xff0c;因为它…

VR教育:让教育“可视化”,开启元宇宙教学之路

放眼世界&#xff0c;有不少高等教育学校都已经开始了元宇宙教学之路&#xff0c;为了从根本上解决目前课堂教学中存在的问题&#xff0c;进一步提高课堂教学质量&#xff0c;VR教育就可以很好地完善这些方面。 传统教育并不能让学生很好地沉浸在真实知识环境中&#xff0c;在一…

连锁门店运营管理系统有哪些功能?该如何选购?

连锁门店运营管理过程中&#xff0c;面临诸多难题&#xff0c;比如不同门店分布在不同地区&#xff0c;管理分散&#xff1b;各门店的人员管理、绩效考核、销售数据等工作进行困难&#xff1b;很难保证产品和服务的标准化管控。 连锁店只有不断适应市场变化&#xff0c;趁早选择…

不用运算符的加法运算

一.不用运算符的加法 1.题目描述 设计一个函数把两个数字相加。不得使用 或者其他算术运算符。 力扣:力扣 2.问题分析 1.知识预备 注意:下面所有的结论的进位是考虑二进制的进位,因为我们使用的位运算符,是针对二进制进行的. 结论一:在不考虑进位的情况下&#xff0c;其无…

【group by】mysql分组查询的案例和原理

【group by】mysql分组查询的案例和原理 【一】group by的使用场景【二】group by的基本语法【1】基本语法【2】常用的聚合函数&#xff08;1&#xff09;max函数&#xff1a;取出分组中的最大值&#xff08;2&#xff09;avg函数&#xff1a;取出分组中的平均值&#xff08;3&…

斩获大奖!「智办事绩效」荣获钉钉年度奖项-「含钉量新锐奖」

近日&#xff0c;钉钉发布「含钉量年度奖」榜单&#xff0c;「智办事绩效」凭借与钉钉的深度融合斩获钉钉年度奖项-「含钉量新锐奖」。 ​作为钉钉优质合作伙伴&#xff0c;智办事绩效致力于用数字化、智能化的产品与专业的服务&#xff0c;解决传统绩效管理、人才培养痛点&…

【JOSEF约瑟 JDL-5200A 电流继电器 过负荷或短路启动元件 导轨安装】

名称&#xff1a;电流继电器&#xff1b;品牌&#xff1a;JOSEF约瑟&#xff1b;型号&#xff1a;JDL-5200A触点容量&#xff1a;250V2A&#xff1b;返回时间&#xff1a;≤35ms&#xff1b;整定范围&#xff1a;0.03-19.9A&#xff1b;特点&#xff1a;返回系数高、安装方便。…

前端vue面试题

四、路由 1. Vue-Router 的懒加载如何实现 非懒加载&#xff1a; import List from /components/list.vue const router new VueRouter({routes: [{ path: /list, component: List }] })&#xff08;1&#xff09;方案一(常用)&#xff1a;使用箭头函数import动态加载 co…

content-visibility:可以提高项目的渲染性能

文章目录 一、前言二、浏览器支持程度三、CSS Containment四、跳过具有 content-visibility 的渲染工作五、关于accessibility的说明六、使用contains-intrinsic-size指定元素的自然大小七、通过content-visibility: hidden隐藏内容八、对下一幅画的交互影响(INP) 一、前言 co…

chatgpt赋能python:Python中*para:使用一个参数解决多个参数

Python中*para&#xff1a;使用一个参数解决多个参数 Python是广泛使用的编程语言之一&#xff0c;它非常灵活&#xff0c;可扩展性强&#xff0c;可以通过许多不同的方式实现编程目标。在Python中&#xff0c;有一种非常有用的特性&#xff0c;那就是使用para来代替多个参数。…

微信小程序原生开发功能合集十六:系统主页实现

本章实现小程序主页开发及对应逻辑处理,实现问卷填报相关功能,实现问卷查看、问卷查看、填报历史等功能的实现。   另外还提供小程序开发基础知识讲解课程,包括小程序开发基础知识、组件封装、常用接口组件使用及常用功能实现等内容,具体如下:    1. CSDN课程: http…

ArcGis系列-java发布GP分析结果(带样式)

1&#xff0c;前言 继上一篇 ArcGis系列-java调用GP分析 &#xff0c;已经实现了gp工具的发布&#xff0c;调用&#xff0c;轮询&#xff0c;并已经分别保存好发布地图服务所需的矢量数据json&#xff0c;栅格数据tif文件和样式文件 要将gp分析的结果发布为图层供前端展示&am…

模版的分离编译 解决方案

回顾 对于模版&#xff0c;在之前我们就已经讲过&#xff0c;模版不支持分离编译&#xff08;即声明定义不在同一文件中&#xff09;。 类中&#xff0c;我们知道&#xff0c;对于代码量比较小的函数&#xff0c;会默认识别成内联函数&#xff0c;增加代码运行的效率&#xf…

【LeetCode 142】环形链表II

思路&#xff1a; 本题需要考虑以下两个问题&#xff1a; 判断链表是否环 如果有环&#xff0c;如何找到这个环的入口 一开始想着使用双指针的办法实现&#xff0c;但是发现没有什么思路&#xff0c;后面看了一些解析&#xff0c;用的快慢指针&#xff0c;两个指针重逢了&a…