“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

All of the Spring source code is available for download in my personal Github repository.

The previous article examined the container initialization and packet scanning processes, and the container refresh process continues. From the org. Springframework. Context. Support. AbstractApplicationContext# refresh.

@Override
	public void refresh(a) throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			// Prepare this context for refreshing.
			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			/** * 01 Delegate implementation class refreshes beanFactory, which is the template method design pattern */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			/** * 02 Sets up the BeanFactory classloader, initializes a standard container * instantiates 2 BeanPostProcessors into member variables * manually registers several special beans */
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				/ / 03 expansion point: to subclass to achieve extension Such as the Web container ServletContextAwareProcessor registration
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				//04 Instantiate BeanFactoryPostProcessor and call the post-processing method. It's an extension of BeanFactory
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				/** * 05 First instantiate the ****BeanPostProcessor object (BeanDefinition scanned earlier), because we will need to call the post-processing method when instantiating ordinary beans later. Put the instantiated Processor object into the beanPostProcessors member variable: *@link org.springframework.beans.factory.support.AbstractBeanFactory#beanPostProcessors
				 */
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				/ / the internationalization
				initMessageSource();

				// Initialize event multicaster for this context.
				// Initializes the event broadcaster
				initApplicationEventMulticaster();

				// Initialize other special beans in specific context subclasses.
				/** * 06 Extension point: Allows subclasses to instantiate the specified bean template method design pattern in the specified context. This occurs after a special bean is instantiated, but before a singleton bean is instantiated. * /
				onRefresh();

				// Check for listener beans and register them.
				// 07 Register event listeners (classes that implement the ApplicationListener interface)
				registerListeners();

				/** * 08 Instantiate bean */
				// Instantiate all remaining (non-lazy-init) singletons.
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...resetCommonCaches(); }}}Copy the code
  1. Get the BeanFactory container

Annotation-based container, at the beginning of the init () method, call the superclass constructor new out an DefaultListableBeanFactory, so don’t need to repeat to create here.

protected ConfigurableListableBeanFactory  obtainFreshBeanFactory(a) {
		/ * * * for AnnotationConfigApplication - > GenericApplicationContext, there is no need to scan the bean definition. Because in the previous 02 calls the scan for other containers () method is * and ClassPathXmlApplicationContext - > AbstractRefreshableApplicationContext, have their own implementation, It will finish parsing the beanDefinition. * /
		refreshBeanFactory();
		ConfigurableListableBeanFactory beanFactory = getBeanFactory();
		if (logger.isDebugEnabled()) {
			logger.debug("Bean factory for " + getDisplayName() + ":" + beanFactory);
		}
		return beanFactory;
	}
Copy the code
  1. Standard initialization of containers
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		// Tell the internal bean factory to use the context's class loader etc.
		beanFactory.setBeanClassLoader(getClassLoader());
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// Configure the bean factory with context callbacks.
		/** * Register beanPostProcessors to member variables * to pass the ApplicationContext context to the implementation {@link EnvironmentAware}, {@link EmbeddedValueResolverAware},
		 *  {@link ResourceLoaderAware}, {@link ApplicationEventPublisherAware},{@link MessageSourceAware} and/or {@linkThe object of the ApplicationContextAware} interface * [this is how the Spring container context is encoded] */
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
		// Ignore these Spring built-in beans for dependency injection, which should not be directly injected.
		beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
		beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
		beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
		beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
		beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

		// BeanFactory interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		// Register with IOC dependency injection
		beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
		beanFactory.registerResolvableDependency(ResourceLoader.class, this);
		beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
		beanFactory.registerResolvableDependency(ApplicationContext.class, this);

		// Register early post-processor for detecting inner beans as ApplicationListeners.
		/** * registers the bean that implements the ApplicationListener interface */
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

		// Detect a LoadTimeWeaver and prepare for weaving, if found.
		if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			// Set a temporary ClassLoader for type matching.
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}

		// Register default environment beans.
		if(! beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); }if(! beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME,  getEnvironment().getSystemProperties()); }if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}
Copy the code
  • Container instantiation ApplicationContextAwareProcessor, used to pass ApplicationContext context
  • Instantiation ApplicationListenerDetector, which scans ApplicationListener listener
  • Instantiation LoadTimeWeaverAwareProcessor, used to detect run-time woven into components. (Dynamic proxy)
  1. Is an extension point left to subclasses to implement to handle the BeanFactory, which occurs after standard initialization.

  2. Instantiate the default BeanFactoryPostProcessor and invoke the post-processing method. It’s also an extension of BeanFactory.

BeanFactoryPostProcessor is used to extend the processing of beans inside the container. PostProcessBeanFactory () allows you to overwrite or add attributes to the Bean before instantiating it. Unlike BeanPostProcessor, it can only postprocess BeanDefinitions inside containers (before instantiation).

4.1 Instantiating a hardcoded Postprocessor Object

/** * 4.1 Instantiate the hard-coded registered afterprocessor */
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
					registryProcessors.add(registryProcessor);
				}
				else{ regularPostProcessors.add(postProcessor); }}Copy the code

4.2 Scanning the Configured BeanFactoryPostProcessor

/** * 4.2 Instantiate the configured post-processor */
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true.false);
			for (String ppName : postProcessorNames) {
				if(beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); }}Copy the code

4.3 Instantiating All PostProcessor types

List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (processedBeans.contains(ppName)) {
				// skip - already processed in first phase above
			}
			else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
			}
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else{ nonOrderedPostProcessorNames.add(ppName); }}Copy the code

4.4 Invoking the PostProcessor Method

sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : orderedPostProcessorNames) {
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
Copy the code
  1. BeanDefinition of type ***BeanPostProcessor is scanned in the init() method and added to the beanPostProcessors property in the factory.

BeanPostProcessor is also one of the most important extension properties of the Spring container.

BeanPostProcessor is a chain of responsibility mode in which all Beanpostprocessors hang on one chain. The basic initialization process is similar to the BeanFactory process in 4, except that this step only completes the instantiation, but does not invoke the POST method.

/** public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { ......... Omit code /** * 5.3 Split sorted and unsorted */
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				// Instantiates the PostProcessor that implements the PriorityOrdered interface
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				if (pp instanceofMergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); }}else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
				orderedPostProcessorNames.add(ppName);
			}
			else{ nonOrderedPostProcessorNames.add(ppName); }}/** 5.4 Register PostProcessor objects that implement PriorityOrdered interfaces instantiated in 5.3 and placed in the BeanFactory factory */
		// First, register the BeanPostProcessors that implement PriorityOrdered.
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		/** * 5.5 instantiate PostProcessor */
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
		for (String ppName : orderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		// 5.6 Instantiate regular beans and register all unordered BeanPostProcessors
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
		for (String ppName : nonOrderedPostProcessorNames) {
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			if (pp instanceof MergedBeanDefinitionPostProcessor) {
				internalPostProcessors.add(pp);
			}
		}
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		/** * 5.7 Register all internal BeanPostProcessors again?? It seems that the order of BeanPostProcessor has been replaced. * no repeat registered is MergedBeanDefinitionPostProcessor types of PostProcessor * * so the subtotal, BeanPostProcessor order: PriorityOrdered - > Order - > regular - > MergedBeanDefinitionPostProcessor type * /
		sortPostProcessors(internalPostProcessors, beanFactory);
		registerBeanPostProcessors(beanFactory, internalPostProcessors);

		// Re-register post-processor for detecting inner beans as ApplicationListeners,
		// moving it to the end of the processor chain (for picking up proxies etc).
		// 5.8 Register the post-processor to discover the event listener again, which is placed at the bottom.
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}
Copy the code

The general steps are:

  • Get the BeanDefinition of type BeanPostProcessor from the BeanFactory
  • Start separating and sorting as PriorityOrdered -> Order -> regular
  • Instantiate the BeanDefinition and put the List beanPostProcessors member variable
  1. Extension points leave to subclasses a template method that can be implemented on demand.

  2. Register event listeners

protected void registerListeners(a) {
		// Register statically specified listeners first.
		/** * 7.1 Get the hardcoded Set
      
       > applicationListeners */
      >
		for(ApplicationListener<? > listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); }// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let post-processors apply to them!
		/** * 7.2 Obtain the scanned ApplicationListener type */
		String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true.false);
		for (String listenerBeanName : listenerBeanNames) {
			getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
		}

		// Publish early application events now that we finally have a multicaster...
		Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
		this.earlyApplicationEvents = null;
		if(earlyEventsToProcess ! =null) {
			for(ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); }}}Copy the code
  1. Instantiate the Bean

Start instantiating all non-lazy-loaded beans

public void preInstantiateSingletons(a) throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("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.
		// 8.1 In the previous scan, this.beanDefinitionNames holds the names of all BeanDefinitions
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// Loop to initialize the bean
		for (String beanName : beanNames) {
			// Merge attributes in the parent class (if any)
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// Non-abstract, singleton, non-lazy loading.
			if(! bd.isAbstract() && bd.isSingleton() && ! bd.isLazyInit()) {if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceofFactoryBean) { FactoryBean<? > factory = (FactoryBean<? >) bean;boolean isEagerInit;
						if(System.getSecurityManager() ! =null && factory instanceofSmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<? >) factory)::isEagerInit, getAccessControlContext()); }else {
							isEagerInit = (factory instanceofSmartFactoryBean && ((SmartFactoryBean<? >) factory).isEagerInit()); }if(isEagerInit) { getBean(beanName); }}}else {
					// 8.2 [Important] Start bean initialization entrygetBean(beanName); }}}Copy the code

getBean() -> doGetBean()

It mainly consists of several steps

  • If beanName does not exist, it will be exposed in the first place. Add Map

    earlySingletonObjects.
    ,>
  • Determine whether the parent factory exists
  • None of the beans on which the target Bean depends are recursively instantiated to start creation.
  • CreateBean() -> doCreateBean()
  • Check the type of the Bean and return the Bean if the type is consistent

There are a few simple ways to illustrate:

getObjectForBeanInstance()

If it is a plain Bean, it returns sharedInstance directly; if it is a FactoryBean, it returns the instance object it created

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

		/** * This method is called to check whether the current bean is a bean of type FactoryBean. If it is, getObject() of the bean's corresponding FactoryBean instance is called as the return value, not */
		// Don't let calling code try to dereference the factory if the bean isn't a factory.
		if (BeanFactoryUtils.isFactoryDereference(name)) {
			if (beanInstance instanceof NullBean) {
				return beanInstance;
			}
			if(! (beanInstanceinstanceof FactoryBean)) {
				throw newBeanIsNotAFactoryException(beanName, beanInstance.getClass()); }}// 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.
		// Non-factory beans are returned directly
		if(! (beanInstanceinstanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
			return beanInstance;
		}

		/ / load FactoryBean
		Object object = null;
		if (mbd == null) {
			// In the previous singleton, it was possible to initialize it directly by the object factory
			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);
			}
			booleansynthetic = (mbd ! =null && mbd.isSynthetic());

			// Important: Actually get bean instances from factoryBeans, delegating parsing beans from Factory to getObjectFromFactoryBeanobject = getObjectFromFactoryBean(factory, beanName, ! synthetic); }return object;
	}
Copy the code

Beans retrieved from the cache or loaded by different Scope policies are just the raw bean state. What we really need is the bean returned from the factory-method method defined in the factory bean,BeanPostProcessor The afterprocessor is implemented here.

The doCreateBean method is where the bean is actually instantiated. Some preparation is done in the Create() method before instantiating the bean

  • Method overriding
  • Aop processing, if enhanced, returns the Bean object directly here. InstantiationAwareBeanPostProcessors type extension processor handling of aop before initialization.

DoCreateBean () : Starts creating the Bean

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			01 Reflection call constructor to create bean instanceinstanceWrapper = 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.
		/ * * * 02 post-processing bean method for treatment of MergedBeanDefinitionPostProcessor * only deals with the types of PostProcessor, other types of processing below. * /
		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.
		// 03 Early exposure resolves cyclic dependencies
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				logger.debug("Eagerly caching bean '" + beanName +
						"' to allow for resolving potential circular references");
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		// 04 Populating bean properties (including @autowire)
		Object exposedObject = bean;
		try {
			/** * [important] 05 Populating the bean's properties * this step is also critical. This step is responsible for the property assembly, because the previous instance was instantiated without setting the value
			populateBean(beanName, mbd, instanceWrapper);
			/** * 【 important 】 06 Remember init-method? And the InitializingBean interface? And the BeanPostProcessor interface? PostBeforeInit() -> init() -> PostAfterInit() */
			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.
		/** * 05 Extension: Check whether the Bean needs to call destruction when the container is closed. Spring provides an extension to the initialization method as well as to the destruction method */ if you need to put it to the variable Map
      
        disposableBeans
      ,>
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
		}

		/ / return the Bean
		return exposedObject;
	}
Copy the code
  • Call the constructor to create an instance of the Bean
  • Treatment MergedBeanDefinitionPostProcessor type of rear extension methods
  • Pre-exposed beans
  • Populate the Bean’s properties
  • Start handling the various callback interfaces after Bean initialization, including init, postProcessor, and so on

CreateBeanInstance () :

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);// Check class access permissions
		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 {
				// No parameter constructor
				returninstantiateBean(beanName, mbd); }}// Candidate constructors for autowiring?
		// Determine whether to use the parameter constructorConstructor<? >[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if(ctors ! =null|| mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || ! ObjectUtils.isEmpty(args)) {return autowireConstructor(beanName, mbd, ctors, args);
		}

		// No special handling: simply use no-arg constructor.
		// When no constructor is specified, the object is initialized by calling the constructor without arguments
		return instantiateBean(beanName, mbd);
	}
Copy the code

initializeBean()

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;
		if (mbd == null| |! mbd.isSynthetic()) {/ / 01 BeanPostProcessor postProcessBeforeInitialization callback
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// 02 Calls the initialization method
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw newBeanCreationException( (mbd ! =null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null| |! mbd.isSynthetic()) {/ / 03 BeanPostProcessor postProcessAfterInitialization callback
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
Copy the code

At this point, the initialization of a Bean is complete, and this is where most BeanPostProcessors implement extended beans.

The startup process of an IOC container based on annotations mainly includes three parts: 1. Initialize the Bean container, resource path scanner, etc. 2. Scan beanDefinitions based on Resource and select beans to be assembled based on TypeFilter. 4.Spring’s extension mechanism is very flexible, including initializing a bunch of classes that implement the BeanPostProcessor interface. At different stages of a container’s life cycle, pick them out for callback processing. There are also a number of template method patterns that subclasses can implement and call back. 5.Spring’s business method organizes a large method that contains many small lUs, and the real work method is to do… Name at the beginning. The rest of the way is to do the preparatory work.

There are some more detailed processes that need to be discussed in the following articles

1. The specific implementation process of Spring’s singleton or prototype pattern cache factory? 2. How does Spring handle common annotations like @Component and @autowire? 3. How does SpringBoot take advantage of Spring’s extension mechanism to achieve auto-assembly?