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

article/2025/10/26 3:27:36

前言

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

类图

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

调用主流程

public Object getBean(String name) throws BeansException {// 找到做事的方法doGetBeanreturn 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.// 检查单例缓存是否有手动注册的单例,这里涉及到三级缓存// 看详解1Object 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,详见详解2RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);// 检查是否是抽象的,是抽象的报错checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.// 获取DependsOnString[] 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 + "'");}// 注册依赖BeanregisterDependentBean(dep, beanName);try {// 先获取依赖的BeangetBean(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方法,看详解3sharedInstance = 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实例。详看6return adaptBeanInstance(name, beanInstance, requiredType);
}

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

public Object getSingleton(String beanName) {// allowEarlyReference(应该创建早期引用)属性为truereturn 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) {// 去单例工厂。未取到返回nullObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);// 取到单例工厂if (singletonFactory != null) {// 创建一个单例对象singletonObject = singletonFactory.getObject();// 放入早期单例对象this.earlySingletonObjects.put(beanName, singletonObject);// 从工厂中移除this.singletonFactories.remove(beanName);}}}}}}// 有4中情况的返回 单例对象、早期单例对象、单例工厂、nullreturn singletonObject;
}

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

protected Object getObjectForBeanInstance(Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {// 当前创建的BeanString 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属性置为trueif (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创建一个Beanobject = 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) {// 本身就是直接clonembd = ((RootBeanDefinition) bd).cloneBeanDefinition();}else {// bd转为RootBeanDefinitionmbd = new RootBeanDefinition(bd);}}// 有父定义的名称else {// Child bean definition: needs to be merged with parent.// 子定义需要merged给父定义BeanDefinition pbd;try {// 获取父BeanNameString parentBeanName = transformedBeanName(bd.getParentName());// 与父名称不一样if (!beanName.equals(parentBeanName)) {// 合并pbd = getMergedBeanDefinition(parentBeanName);}else {// 得到父BeanFactoryBeanFactory parent = getParentBeanFactory();if (parent instanceof ConfigurableBeanFactory) {// 从父BeanFactory得到BeanDefinitionpbd = ((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) {// 判断是否正在销毁,默认属性为falseif (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.1singletonObject = 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.2Class<?> resolvedClass = resolveBeanClass(mbd, beanName);// 有解析到class 且 不是BeanClass 且 有BeanClassNameif (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.3Object 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.// 实例化一个beanBeanWrapper 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://chatgpt.dhexx.cn/article/rlL6vfkp.shtml

相关文章

Spring中关于getBean()报强制转化错误

在自学Spring时&#xff0c;在使用getBean()时&#xff0c;会报com.sakura.dao.impl.BookDaoImpl cannot be cast to com.sakura.dao.BookDao at com.sakura.App2.main(App2.java:19) 这个错误表示&#xff0c;不能将一个实现类BookDaoImpl类强转为BookDao接口。这个错&#…

spring源码解读之getBean方法(一)

前言 大家使用spring&#xff0c;最常接触到的就是bean&#xff0c;大家也知道spring中用一句getBean就能取出一个实例化好的bean&#xff0c;这个bean是属于IOC容器管理的&#xff0c;那么大家有没有看过getBean方法的源码呢&#xff0c;知不知道spring容器到底是怎么得到一个…

Spring源码之getBean(获取 bean)方法(一)解读

目录 测试类一个简单的测试类对于 ApplicationContext 和 ClassPathXmlApplicationContext 类图如下getBean() 源码解读查看 AbstractApplicationContext 中的 getBean 方法查看 AbstractBeanFactory 的 doGetBean 方法看 doGetBean 方法的流程图分析doGetBean 方法的主要流程 …

JavaBean(set和get方法)

JavaBean的规范 类中所有的成员属性都是私有&#xff0c;也就是 private 来修饰 提供一个公共无参数的构造方法 为所有私有的属性提供公共的 set 和 get 方法。 set方法 set 方法是有参数无返回值的&#xff0c;目的是通过 set 方法给 javabean 中的私有属性赋值&#xff0c;…

getBean方法源码

一、 三个API // 根据name获取bean Override public Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false); }// 根据name获取bean&#xff0c;如果获取到的bean和指定类型不匹配&#xff0c;则抛出异常 Override public <T>…

详解Spring中getBean()方法

我们日常会经常使用getBean()方法从spring容器中获取我们需要的bean。那么&#xff0c;getBean()方法是怎么一步步完成从spring容器中获取bean的呢&#xff1f; 下面我们就通过源码分析一下。 一、主要代码分析 基于&#xff1a;spring5.1 入口&#xff1a;AbstractBeanFactory…

getBean方法(一)

我们先看看这个方法的轮廓流程 这个getbean的轮廓方法很长. 先分两种情况: 一种是在缓存实例中能拿到bean, (主要是factroyBean的处理, 执行所有已注册的 BeanPostProcessor 的 postProcessAfterInitialization 方法) 前边是校验 (如果name以“&”为前缀&#xff0c;但是b…

Spring源码分析之getBean主流程分析

当我们通过向Spring容器获取某个bean的时候&#xff0c;总是调用Spring中重载的各种getBean方法。那么&#xff0c;getBean中的流程是什么样的&#xff1f; 通过本文&#xff0c;你将对getBean方法的主流程有一个详细的认识。 入口当然是getBean方法&#xff1a; public Obje…

getBean( )流程

getBean() 方法是顶层接口 BeanFactory 提供的&#xff0c;一共五个原型。AbstractBeanFactory作为抽象实现&#xff0c;复写了其中3个方法&#xff0c; Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}Overr…

Prometheus监控MongoDB数据库

监控环境&#xff1a;Prometheus 数据库&#xff1a;MongoDB 3.4.6 集群&#xff0c;3个节点 监控工具&#xff1a;mongodb_exporter 我这个模板是自己二次开发的。使用mongodb_exporter 监控 阿里云的MongoDB数据库 各位根据自己的需求进行使用 1、创建Mongodb监控可读账…

DBeaver 数据库管理工具

DBeaver 数据库管理工具 DBeaver 是一个基于 Java 开发&#xff0c;免费开源的通用数据库管理和开发工具&#xff0c;使用非常友好&#xff0c;且遵循ASL 协议。由于 DBeaver 基于 Java 开发&#xff0c;可以运行在各种操作系统上&#xff0c;比如Windows、Linux、macOS 等操作…

mysql数据库监控

MySQL是一个关系型数据库管理系统&#xff0c;由瑞典MySQL AB 公司开发&#xff0c;属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一&#xff0c;在 WEB 应用方面&#xff0c;MySQL是最好的 RDBMS (Relational Database Management System&#xff0c;关系数据…

一些数据库监控,优化,管理工具

http://www.itpub.net/viewthread.php?tid1057814&extra&page1 一些数据库监控,优化,管理工具 ******************************************************************* 这两天网盘连不上了&#xff0c;导致国内用户暂时无法下载。大家下载时需要用代理。这里提供一个比…

oracle实时监控工具

oracle实时监控工具市面上不多&#xff0c;但是兼具数据维护管理及性能实时监控的工具可以说更少&#xff0c;而实时监控又是项目运维管理&#xff0c;测试&#xff0c;开发但环节不可少的功能&#xff0c;目前有一款JAVA开发的&#xff0c;基于WEB的&#xff1a;TreeSoft数据库…

数据库的可用监控

监控 数据库是否连接和读写以及数据库的连接数 1、确认数据库是否可以通过网络连接 造成连接不成功的原因&#xff1a;防火墙 TCP/IP连接被占满 监控的方式&#xff1a; 1、mysqladmin -u 监控用户 -p 密码 -h 监控的服务器地址 ping 首先我们在MySQL下要建立一个mysql 的用户…

数据库实时监控,实时监控数据库数据

为了满足大多数用户对数据库的监控和运维需求&#xff0c;系统实时采集了监控数据库的主要指标&#xff0c;并提供完整的报警、性能容量分析和报告功能。  系统以数字形式收集现场设备发送的数据&#xff0c;通过实时数据操作实现监控功能&#xff0c;并提供有利于监控生产过…

数据库监控工具SQL Monitor:可同时实现云和本地的SQL Server数据库监视

SQL Monitor提供了一个基于Web的监视&#xff0c;在桌面计算机和移动设备上实时地监控服务器的性能。使用SQL Monitor时&#xff0c;只要一出现问题&#xff0c;你将会通过邮件和用户界面接收到警告&#xff0c;SQL Monitor会快速地做全局检查&#xff0c;检查单机&#xff0c;…

mysql实时监控工具

mysql实时监控工具市面上有许多了&#xff0c;但是兼具数据维护管理及性能实时监控的工具不多&#xff0c;可以说很少&#xff0c;而实时监控又是项目运维管理&#xff0c;测试&#xff0c;开发但环节不可少的功能&#xff0c;目前有一款JAVA开发的&#xff0c;基于WEB的&#…

数据库监控

数据库监控 一、数据库监控介绍 1、对什么进行监控 (1) 对数据库服务可用性进行监控 数据库进程或是端口存在并不意味着数据库就是可用的&#xff1b; 通过网络连接到数据库并且确定数据库是可以对外提供服务的。 (2) 对数据库性能进行监控 QPS和TPS&#xff1b; 并发线程数量…

MySQL - 数据库的监控方式

对于当前数据库的监控方式有很多&#xff0c;分为数据库自带、商用、开源三大类&#xff0c;每一种都有各自的特色&#xff1b; 而对于 mysql 数据库由于其有很高的社区活跃度&#xff0c;监控方式更是多种多样&#xff0c;不管哪种监控方式最核心的就是监控数据&#xff0c;获…