zoukankan      html  css  js  c++  java
  • spring 学习-bean创建bean

    概述

    spring 生成 bean 的文章分为两部分 , 一部分是正常生成一个 component 的过程 ,而另外一篇则是通过循环依赖梳理 spring 框架是如何解决循环依赖 ,并成功生成 bean 的

    我还是把之前的重要的几张类机构继承图放出来

    1297993-20210802232756810-429752981.png

    1297993-20210817215722882-1209468791.png

    Demo

    @Service
    public class A {
    }
    

    我们跟踪一个bean 是如何生成的 .

    代码分析

    上一节我们讲到 refresh 方法中调用 preInstantiateSingletons 方法 , 而 preInstantiateSingletons 中会调用 getBean 方法完成 bean 的生成.

    @Override
    public void preInstantiateSingletons() throws BeansException {
    	if (logger.isTraceEnabled()) {
    		logger.trace("Pre-instantiating singletons in " + this);
    	}
    
    	// Iterate over a copy to allow for init methods which in turn register new bean definitions.
    	// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
    	List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
    	// Trigger initialization of all non-lazy singleton beans...
    	for (String beanName : beanNames) {
    		RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    		if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    			if (isFactoryBean(beanName)) {
    				Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    				if (bean instanceof FactoryBean) {
    					final FactoryBean<?> factory = (FactoryBean<?>) bean;
    					boolean isEagerInit;
    					if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
    						isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
    										((SmartFactoryBean<?>) factory)::isEagerInit,
    								getAccessControlContext());
    					}
    					else {
    						isEagerInit = (factory instanceof SmartFactoryBean &&
    								((SmartFactoryBean<?>) factory).isEagerInit());
    					}
    					if (isEagerInit) {
    						getBean(beanName);
    					}
    				}
    			}
    			else {
    				// 调用 getBean 方法 
    				getBean(beanName);
    			}
    		}
    	}
    
    	// Trigger post-initialization callback for all applicable beans...
    	for (String beanName : beanNames) {
    		...
    	}
    }
    
    

    getBean 方法

    	@Override
    	public Object getBean(String name) throws BeansException {
    		return doGetBean(name, null, null, false);
    	}
    
    	/**
    	 *  这个方法主要完成 3 个步骤的逻辑 :
    	 *  1. 转换 beanName 
    	 *  2. 生成 bean  
    	 *  3. 判断该 bean 是否需要转型 
    	 * 
    	 */
    	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
    			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
    
    		final String beanName = transformedBeanName(name);
    		Object bean;
    
    		// Eagerly check singleton cache for manually registered singletons.
    		// 重要逻辑 A : 早期检查是否存在单例缓存 
    		// 先看重要逻辑 A , 理解后继续往下看代码  
    		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 + "'");
    				}
    			}
    			//
    			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 definition 是否已经存在该 factory 中 
    			// todo 后续再分析这是啥情况 
    			BeanFactory parentBeanFactory = getParentBeanFactory();
    			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) {
    				markBeanAsCreated(beanName);
    			}
    
    			/**
    			 * 主要逻辑就是 : 
    			 * 1. 找到依赖 ,递归调用 getBean 方法(我们代码也是从 getBean 中进来的),生成实例
    			 * 
    			 */
    			try {
    				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    				checkMergedBeanDefinition(mbd, beanName, args);
    
    				// Guarantee initialization of beans that the current bean depends on.
    				// 找依赖! 调用 getBean 方法 
    				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 + "'");
    						}
    						registerDependentBean(dep, beanName);
    						try {
    							getBean(dep);
    						}
    						catch (NoSuchBeanDefinitionException ex) {
    							throw new BeanCreationException(mbd.getResourceDescription(), beanName,
    									"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
    						}
    					}
    				}
    
    				// 看这里 !!!! 这才是真正创建实例的地方!!! 
    
    				// Create bean instance.
    				if (mbd.isSingleton()) {
    					//重要逻辑 B :  第二个参数是个匿名参数 
    					sharedInstance = getSingleton(beanName, () -> {
    						try {
    							//重要逻辑 C : 走这里初始化对象
    							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;
    						}
    					});
    
    					bean = 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);
    					}
    					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    				}
    
    				else {
    					String scopeName = mbd.getScope();
    					final 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);
    							}
    						});
    						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    					}
    					catch (IllegalStateException ex) {
    						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) {
    				cleanupAfterBeanCreationFailure(beanName);
    				throw ex;
    			}
    		}
    
    		// Check if required type matches the type of the actual bean instance.
    		if (requiredType != null && !requiredType.isInstance(bean)) {
    			try {
    				T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
    				if (convertedBean == null) {
    					throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    				}
    				return 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;
    	}
    
    

    getSingleton 方法 , 看方法名就是获取单例 ,

    
    @Override
    @Nullable
    public Object getSingleton(String beanName) {
    	return getSingleton(beanName, true);
    }
    
    
    	/**
    	 * Return the (raw) singleton object registered under the given name.
    	 * <p>Checks already instantiated singletons and also allows for an early
    	 * reference to a currently created singleton (resolving a circular reference).
    	 * @param beanName the name of the bean to look for
    	 * @param allowEarlyReference whether early references should be created or not
    	 * @return the registered singleton object, or {@code null} if none found
    	 * 
    	 * 这个方法就是解决循环依赖的关键  
    	 * 
    	 */
    	@Nullable
    	protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		// Quick check for existing instance without full singleton lock
    		// 在单例列表中查询是否存在单例对象
    		Object singletonObject = this.singletonObjects.get(beanName);
    		// 不存在 , 且存在 "并发单例对象列表" 中 
    		// 我们的例子中 , "a" 这个实例没有循环依赖的情况 ,所以到了下面的 if 为 false 后 ,直接就返回了 
    		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
    					// 这个地方有点像单例模式, DCK 双锁 , 这里使用的是线程安全的列表
    					singletonObject = this.singletonObjects.get(beanName);
    					if (singletonObject == null) {
    						singletonObject = this.earlySingletonObjects.get(beanName);
    						if (singletonObject == null) {
    							ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    							if (singletonFactory != null) {
    								singletonObject = singletonFactory.getObject();
    								this.earlySingletonObjects.put(beanName, singletonObject);
    								this.singletonFactories.remove(beanName);
    							}
    						}
    					}
    				}
    			}
    		}
    		return singletonObject;
    	}
    
    
    	=====================================================
    
    	/**
    	 * Return the (raw) singleton object registered under the given name,
    	 * creating and registering a new one if none registered yet.
    	 * @param beanName the name of the bean
    	 * @param singletonFactory the ObjectFactory to lazily create the singleton
    	 * with, if necessary
    	 * @return the registered singleton object
    	 */
    	public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    		Assert.notNull(beanName, "Bean name must not be null");
    		synchronized (this.singletonObjects) {
    			Object singletonObject = this.singletonObjects.get(beanName);
    			if (singletonObject == null) {
    				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 + "'");
    				}
    				beforeSingletonCreation(beanName);
    				boolean newSingleton = false;
    				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
    				if (recordSuppressedExceptions) {
    					this.suppressedExceptions = new LinkedHashSet<>();
    				}
    				try {
    					// 刚才我们说第二个参数是匿名参数 !! 
    					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;
    		}
    	}
    

    createBean 方法 , 方法内我们标注了几个逻辑.

    	/**
    	 * Central method of this class: creates a bean instance,
    	 * populates the bean instance, applies post-processors, etc.
    	 * @see #doCreateBean
    	 * 
    	 * 翻译 : 这个类的中心方法:创建一个 bean 实例,填充 bean 实例,应用后处理器等。
    	 * 
    	 */
    	@Override
    	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.
    		// 这里会生成一个class对象 , class 对象可以还没有实例化 
    		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    		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.
    			// 重要逻辑 D : 这里需要注意一下 , 假如返回的 bean ! = null  ,返回就结束了
    			// 这个地方就给我们可以自定义生成 bean 的可能, 我们在后续的文章会介绍的它的应用 
    			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 {
    			// 重要逻辑 D : 这里地方才是真正生成实例的地方!!!
    			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);
    		}
    	}
    
    

    重要逻辑 D

    	/**
    	 * 重要逻辑 D 
    	 * 
    	 * Apply before-instantiation post-processors, resolving whether there is a
    	 * before-instantiation shortcut for the specified bean.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @return the shortcut-determined bean instance, or {@code null} if none
    	 */
    	@Nullable
    	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.
    			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    				Class<?> targetType = determineTargetType(beanName, mbd);
    				if (targetType != null) {
    					// 应用上 BeanPostProcess 的 BeforeInstantiation 方法 
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						// 假如生成了一个 bean , 应用上 BeanPostProcess 的 AfterInitialization 方法 
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    

    继续往下走

    	/**
    	 * Actually create the specified bean. Pre-creation processing has already happened
    	 * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
    	 * <p>Differentiates between default bean instantiation, use of a
    	 * factory method, and autowiring a constructor.
    	 * @param beanName the name of the bean
    	 * @param mbd the merged bean definition for the bean
    	 * @param args explicit arguments to use for constructor or factory method invocation
    	 * @return a new instance of the bean
    	 * @throws BeanCreationException if the bean could not be created
    	 * @see #instantiateBean
    	 * @see #instantiateUsingFactoryMethod
    	 * @see #autowireConstructor
    	 * 
    	 * 方法注释说明了这才是真正形成特定 bean 的地方
    	 */
    	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
    			throws BeanCreationException {
    
    		// Instantiate the bean.
    		// 重点来啦 !!!!实例化 bean 啦 !!!!
    		// 1. 生成实例 
    		BeanWrapper instanceWrapper = null;
    		if (mbd.isSingleton()) {
    			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    		}
    		if (instanceWrapper == null) {
    			// 重要逻辑 F : 创建  bean 实例 
    			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.
    		// 允许 post-processors 合并的 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.
    		// 早期缓存单例实例为了解决循环依赖的问题 
    		// 重要逻辑 F :  这里地方在解决依赖的时候会进入这个循环 , 我们也会在下一篇文章讲解到
    		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.
    		// 重要逻辑 G : 初始化 bean 的实例 
    		// 2. 初始化 bean 的实例 
    		Object exposedObject = bean;
    		try {
                // 该方法会去寻找该 bean 所持有的字段 , 并递归调用 getBean 方法  
    			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;
    	}
    
    

    重要逻辑 F

    
    
    
    
    	/**
    	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
    	 * factory method, constructor autowiring, or simple instantiation.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @param args explicit arguments to use for constructor or factory method invocation
    	 * @return a BeanWrapper for the new instance
    	 * @see #obtainFromSupplier
    	 * @see #instantiateUsingFactoryMethod
    	 * @see #autowireConstructor
    	 * @see #instantiateBean
    	 */
    	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    		// Make sure bean class is actually resolved at this point.
    		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);
    		}
    
    		if (mbd.getFactoryMethodName() != null) {
    			return instantiateUsingFactoryMethod(beanName, mbd, args);
    		}
    
    		// Shortcut when re-creating the same 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);
    	}
    
    

    以我们的 Demo 为例子 , 找到我们创建 instance 的地方

    
    
    	// 使用 CGLIB 反射生成一个示例 
    	@Override
    	public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    		// Don't override the class with CGLIB if no overrides.
    		if (!bd.hasMethodOverrides()) {
    			Constructor<?> constructorToUse;
    			synchronized (bd.constructorArgumentLock) {
    				constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
    				if (constructorToUse == null) {
    					final Class<?> clazz = bd.getBeanClass();
    					if (clazz.isInterface()) {
    						throw new BeanInstantiationException(clazz, "Specified class is an interface");
    					}
    					try {
    						if (System.getSecurityManager() != null) {
    							constructorToUse = AccessController.doPrivileged(
    									(PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
    						}
    						else {
    							constructorToUse = clazz.getDeclaredConstructor();
    						}
    						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
    					}
    					catch (Throwable ex) {
    						throw new BeanInstantiationException(clazz, "No default constructor found", ex);
    					}
    				}
    			}
    			return BeanUtils.instantiateClass(constructorToUse);
    		}
    		else {
    			// Must generate CGLIB subclass.
    			return instantiateWithMethodInjection(bd, beanName, owner);
    		}
    	}
    
    

    CGLIB 是什么 ?

    CGLIB 动态代理 : https://blog.csdn.net/danchu/article/details/70238002

    重要逻辑 G

    	/**
    	 * Populate the bean instance in the given BeanWrapper with the property values
    	 * from the bean definition.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @param bw the BeanWrapper with bean instance
    	 * 
    	 * 将根据属性值进行填充,例如当 A 里面有一个属性 B , 那么此时就会在该方法中进行递归地调用 getBean 重复我们上面生成 bean 的逻辑  
    	 *
    	 */
    	@SuppressWarnings("deprecation")  // for postProcessPropertyValues
    	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
            .....
        }
    
    /**
    	 * Initialize the given bean instance, applying factory callbacks
    	 * as well as init methods and bean post processors.
    	 * <p>Called from {@link #createBean} for traditionally defined beans,
    	 * and from {@link #initializeBean} for existing bean instances.
    	 * 
    	 * 
    	 * 
    	 * 
    	 * 
    	 * @param beanName the bean name in the factory (for debugging purposes)
    	 * @param bean the new bean instance we may need to initialize
    	 * @param mbd the bean definition that the bean was created with
    	 * (can also be {@code null}, if given an existing bean instance)
    	 * @return the initialized bean instance (potentially wrapped)
    	 * @see BeanNameAware
    	 * @see BeanClassLoaderAware
    	 * @see BeanFactoryAware
    	 * @see #applyBeanPostProcessorsBeforeInitialization
    	 * @see #invokeInitMethods
    	 * @see #applyBeanPostProcessorsAfterInitialization
    	 */
    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    		if (System.getSecurityManager() != null) {
    			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    				invokeAwareMethods(beanName, bean);
    				return null;
    			}, getAccessControlContext());
    		}
    		else {
    			invokeAwareMethods(beanName, bean);
    		}
    
    		Object wrappedBean = bean;
    
    
    		// 前后两个 beanpostprocessor 方法的调用 
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
    		// 这是调用 init 方法 
    		try {
    			invokeInitMethods(beanName, wrappedBean, mbd);
    		}
    		catch (Throwable ex) {
    			throw new BeanCreationException(
    					(mbd != null ? mbd.getResourceDescription() : null),
    					beanName, "Invocation of init method failed", ex);
    		}
    
    
    		// 前后两个 beanpostprocessor 方法的调用 
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    		}
    
    		return wrappedBean;
    	}
    
    

    附录

    DefaultSingletonBeanRegistry 类中的私有字段 , 可以参照阅读代码 .

    // 单例对象的缓存:从beanname到bean实例
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
    // 单例工厂的缓存:从beanname到ObjectFactory
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
    // 早期单例对象的缓存:从beanname到bean实例
    private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
    // 一组已注册的单例,包含按注册顺序排列的beanname
    private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
    // 正在创建的单例的beanName的集合
    private final Set<String> singletonsCurrentlyInCreation = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    // 当前不检查的bean的集合
    private final Set<String> inCreationCheckExclusions = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    // 异常集合
    private Set<Exception> suppressedExceptions;
    // 当前是否在销毁bean中
    private boolean singletonsCurrentlyInDestruction = false;
    // 一次性bean实例
    private final Map<String, Object> disposableBeans = new LinkedHashMap<>();
    // 内部bean和外部bean之间关系
    private final Map<String, Set<String>> containedBeanMap = new ConcurrentHashMap<>(16);
    // 指定bean与依赖指定bean的集合,比如bcd依赖a,那么就是key为a,bcd为value
    private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
    // 指定bean与指定bean依赖的集合,比如a依赖bcd,那么就是key为a,bcd为value
    private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
    

    总结

    • 生成 bean 的大致过程
    1. 调用InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
    2. 实例化Bean
    3. 调用InstantiationAwareBeanProcessor#postProcessAfterInstantiation
    4. 调用InstantiationAwareBeanPostProcessor#postProcessPropertyValues
    5. 为Bean注入属性
    6. 调用BeanNameAware#setBeanName
    7. 调用BeanClassLoaderAware#setBeanClassLoader
    8. 调用BeanFactoryAware#setBeanFactory
    9. 调用BeanPostProcessor#postProcessBeforeInitialization
    10. 调用InitializingBean#afterPropertiesSet
    11. 调用Bean的init-method
    12. 调用BeanPostProcessor#postProcessAfterInitialization
    • spring 通过 getBean 解析对象中的持有的字段 , 并进行递归调用 , 完成对 bean 的实例化

    • spring 解决循环依赖的原理是通过多个集合 (List , Map) 来保存早期引用 , 以此来解决循环依赖

    • 循环依赖的原理可以详见 :

    其中重要的部分 :

    1297993-20210826225201091-191276404.png

    1297993-20210826225223612-9365401.png

    1297993-20210826225259258-1640067995.png

    1297993-20210826225309870-120708870.png

    1297993-20210826225322088-332799640.png

    参考资料

  • 相关阅读:
    支付扣款 并发 异步
    Floyd-Warshall算法
    black arch
    ChromeDriver only supports characters in the BMP
    Getting console.log output with Selenium Python API bindings
    微信公众号文章批量采集系统的构建
    node npm Bower
    PyPy CPython C++ connects programs written in C and C++ with a variety of high-level programming languages
    timeout connect 10000 # default 10 second time out if a backend is not found
    timeout connect 10000 # default 10 second time out if a backend is not found
  • 原文地址:https://www.cnblogs.com/Benjious/p/15191977.html
Copyright © 2011-2022 走看看