SpringIOC initialization process – complete Bean initialization (finishBeanFactoryInitialization)

Have explained the * * in the previous invokeBeanFactoryPostProcessors (the beanFactory); * * method; Let’s see what else we can do

@Override
public void refresh(a) throws BeansException, IllegalStateException {
	synchronized (this.startupShutdownMonitor) {
		// Prepare this context for refreshing.
		// Preparations include setting the startup time, whether to activate the identifier bit,
		// Initialize the property source configuration
		prepareRefresh();

		// Tell the subclass to refresh the internal bean factory.
		// Return a factory
		// Because the factory needs to be initialized
           / * * explain here: if the way you use yes XML configuration is executed AbstractRefreshableApplicationContext refreshBeanFactory method to load the XML configuration information; Because ClassPathXmlApplicationContext is a subclass of it; So now we are using the annotation configuration way will perform GenericApplicationContext refreshBeanFactory method, this method is the only return a the beanFactory * * /
		ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

		// Prepare the bean factory for use in this context.
		// Prepare the factory
		prepareBeanFactory(beanFactory);

		try {
			// Allows post-processing of the bean factory in context subclasses.

			// This method does not use any code in the current version of Spring
			// Perhaps Spring expects this to be extended in a later release
			postProcessBeanFactory(beanFactory);

			// Invoke factory processors registered as beans in the context.
			// Execute the registered Factory Processors in spring's environment
			ProcessBeanFactory is set to execute custom ProcessBeanFactory and spring's own
			invokeBeanFactoryPostProcessors(beanFactory);

			// Register bean processors that intercept bean creation.
			/ / register beanPostProcessor
			registerBeanPostProcessors(beanFactory);

			// Initialize message source for this context.
			// Initialize the MessageSource of the current ApplicationContext
			initMessageSource();

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

			// Initialize other special beans in specific context subclasses.
			// A typical template method (hook method),
			// Specific subclasses can initialize special beans here (before initializing Singleton beans)
			onRefresh();

			// Check for listener beans and register them.
			// Register event listeners that implement the ApplicationListener interface. That's not what we're talking about. Go
			registerListeners();

			// Instantiate all remaining (non-lazy-init) singletons.
			// Point, point, point
			// Initialize all Singleton beans
			// (except lazy-init)
			finishBeanFactoryInitialization(beanFactory);

			// Last step: publish corresponding event.
			// Finally, the event is broadcast and the ApplicationContext initialization is complete
			finishRefresh();
		}
           / /...
Copy the code

Internationalization, initializing application event broadcasters, and registering event listeners won’t be covered here, otherwise it’s really endless; Let’s focus on initializing all singleton Beans methods;

Initialize all the singleton beans – finishBeanFactoryInitialization (the beanFactory);

**finishBeanFactoryInitialization(beanFactory); ** method beans that are not lazily loaded are initialized here;

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// First, initialize the Bean named conversionService. That's not the point
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

		// Register a default embedded value resolver if no bean post-processor
		// (such as a PropertyPlaceholderConfigurer bean) registered any before:
		// at this point, primarily for resolution in annotation attribute values.
		if(! beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); }// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false.false);
		for (String weaverAwareName : weaverAwareNames) {
			getBean(weaverAwareName);
		}

		// Stop using the temporary ClassLoader for type matching.
		beanFactory.setTempClassLoader(null);

		/ / here will beanDefinitionNames assignment to frozenBeanDefinitionNames
		At this point,Spring has preinitialized the Singleton beans.
		// No more bean definitions can be parsed, loaded, or registered;
		beanFactory.freezeConfiguration();

		// Instantiate all remaining (non-lazy-init) singletons.
		// Instantiate all singleton objects
		beanFactory.preInstantiateSingletons();
	}
Copy the code

The focus is on preInstantiateSingletons (); Methods:

public void preInstantiateSingletons(a) throws BeansException {
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		// The names of all beans
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		// Triggers the initialization of all non-lazy loaded singleton beans by calling getBean
		for (String beanName : beanNames) {
			// Merge parent BeanDefinition
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// Whether it is an abstract class, whether it is a singleton, whether it is lazy loading
			if(! bd.isAbstract() && bd.isSingleton() && ! bd.isLazyInit()) {// Whether a FactoryBean is a FactoryBean is a definite no. A future article will cover the difference between a FactoryBean and a BeanFactory
				if (isFactoryBean(beanName)) {
					// If it is a FactoryBean, add &
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						finalFactoryBean<? > 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 {
					// No FactoryBean goes directly to this methodgetBean(beanName); }}}// All non-lazy-loaded Singleton Beans have been initialized
		/ / if we define the bean is realized SmartInitializingSingleton interface, so get back here, ignored
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if(System.getSecurityManager() ! =null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else{ smartSingleton.afterSingletonsInstantiated(); }}}}Copy the code

Focus on the getBean(beanName) method; And the initialization process is encapsulated in this method.

	public Object getBean(String name) throws BeansException {
		return doGetBean(name, null.null.false);
	}
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
			@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		
   	  /** * Get beanName by name. There are two reasons for not using name directly as beanName *. 1. Name may start with an & character, indicating that the caller wants to get the FactoryBean itself, not the bean created by the FactoryBean * implementation class. In BeanFactory, the implementation class of a FactoryBean is the same as that of any other bean, that is, 
      
       . BeanName does not contain the & character. So we need * to remove the first character & of name to get a traditional Bean * 2, or alias problem, the conversion needs * &beanName */
      ,>
		final String beanName = transformedBeanName(name);
        // This is the return value
		Object bean;

		 /** * This method is called on initialization, and also on getBean * why do we need to do this? * This means that spring gets the object when it is initialized * determines whether the object is instantiated * calls at initialization usually return null */
		Object sharedInstance = getSingleton(beanName);
		if(sharedInstance ! =null && args == null) {
			if (logger.isDebugEnabled()) {
				if (isSingletonCurrentlyInCreation(beanName)) {
					//log.....
				}
				else {
					//log.....}}/** * If sharedInstance is a normal singleton bean, the following method returns it directly. But if * sharedInstance is of type FactoryBean, you call the getObject factory method to get the real * Bean instance. If the user wants to get the FactoryBean itself, nothing special is done here, just return *. After all, the implementation class of a FactoryBean is itself a bean, but with a bit of special functionality. * /
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}

		else {
			// Check if the prototype bean is being created and throw an exception if it is already being created
            // Is stuck in a circular dependency
			if (isPrototypeCurrentlyInCreation(beanName)) {
				throw new BeanCurrentlyInCreationException(beanName);
			}

			// Check if the Bean Definition exists in the factory
			BeanFactory parentBeanFactory = getParentBeanFactory();//null
			if(parentBeanFactory ! =null && !containsBeanDefinition(beanName)) {
				// Not found -> check parent.
                // If the BeanDefinition does not exist in the current container, try to find one in the parent container
				String nameToLookup = originalBeanName(name);
				if (parentBeanFactory instanceof AbstractBeanFactory) {
					return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
							nameToLookup, requiredType, args, typeCheckOnly);
				}
                //args is null passed from above
				else if(args ! =null) {
					// Returns the query result of the parent container
					return (T) parentBeanFactory.getBean(nameToLookup, args);
				}
				else {
					// No args -> delegate to the standard getBean method.
					returnparentBeanFactory.getBean(nameToLookup, requiredType); }}// Since parentBeanFactory==null above, the code comes here
			if(! typeCheckOnly) {// Add beanName to the alreadyCreated Set
				markBeanAsCreated(beanName);
			}
		/* * To summarize a bit: * At this point, we are ready to create the Bean, which has not been created in the container for singleton's Bean; For prototype beans, the original idea is to create a new Bean. * /
			try {
                 // Get beanName's corresponding GenericBeanDefinition from the container and convert it to RootBeanDefinition
				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // Check the given merged BeanDefinition
				checkMergedBeanDefinition(mbd, beanName, args);
				// Check dependes-on
				// Initialize all dependent beans first
              // Note that dependency refers to dependence as defined in Depends -on
				String[] dependsOn = mbd.getDependsOn();
				if(dependsOn ! =null) {
                     // Get the depends-on attribute value. If the depends-on value exists, add it to the dependentBeanMap cache
					for (String dep : dependsOn) {
						if (isDependent(beanName, dep)) {
							throw newBeanCreationException(....) ; }// Register dependencies
						registerDependentBean(dep, beanName);
						try {
                            // Initialize the dependents first
							getBean(dep);
						}
						catch (NoSuchBeanDefinitionException ex) {
							throw newBeanCreationException(...) ; }}}// Create the bean instance.
				if (mbd.isSingleton()) {
                    //jdk1.8 Lambda expression, which calls getObject from getSingleton;
					sharedInstance = getSingleton(beanName, () -> {
						try {
                            // Perform the create Bean
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							
							destroySingleton(beanName);
							throwex; }}); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }// If prototype scope, create prototype instance
				else if (mbd.isPrototype()) {
					// It's a prototype -> create a new instance.
					Object prototypeInstance = null;
					try {
						beforePrototypeCreation(beanName);
                        // Perform the create Bean
						prototypeInstance = createBean(beanName, mbd, args);
					}
					finally {
						afterPrototypeCreation(beanName);
					}
					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
				}
			// If not singleton and Prototype, delegate to the corresponding implementation class
				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 {
                                // Perform the create Bean
								return createBean(beanName, mbd, args);
							}
							finally{ afterPrototypeCreation(beanName); }}); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); }catch (IllegalStateException ex) {
						throw newBeanCreationException(...) . }}}catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throwex; }}// Finally, check to see if the type is correct. If not, throw an exception, if not, return an exception.
		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.isDebugEnabled()) {
					//log....
				}
				throw newBeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); }}return (T) bean;
	}
Copy the code

GetSingleton (); jdk1.8 getSingleton(); The getObject() method is called in this method; Enter the getSingleton() method for a quick look:

public Object getSingleton(String beanName, ObjectFactory
        singletonFactory) {
		Assert.notNull(beanName, "Bean name must not be null");
		synchronized (this.singletonObjects) {
            // Currently beanName IndexDaoImpl has not been added to singletonObjects, so null
			Object singletonObject = this.singletonObjects.get(beanName);
			if (singletonObject == null) {
                // Check if it is being destroyed and throw an exception if it is
				if (this.singletonsCurrentlyInDestruction) {
					throw newBeanCreationNotAllowedException(.....) ; }//log.....
				/ * * * will be added to singletonsCurrentlyInCreation beanName such a set in the collection * said beanName corresponding bean is creating in the * /
				beforeSingletonCreation(beanName);
				boolean newSingleton = false;
				boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
				if (recordSuppressedExceptions) {
					this.suppressedExceptions = new LinkedHashSet<>();
				}
				try {
                    // Call the getObject() method, which calls the createBean() in the Lambda expression above.
					singletonObject = singletonFactory.getObject();
					newSingleton = true;
				}
				catch (IllegalStateException ex) {
					/ /...
                    throw ex;
				}
				catch (BeanCreationException ex) {
					/ /...
					throw ex;
				}
				finally {
					if (recordSuppressedExceptions) {
						this.suppressedExceptions = null;
					}
                    // Remove the identifier as being created
					afterSingletonCreation(beanName);
				}
				if (newSingleton) {
                    // Add data to the collection
                 /** * protected void addSingleton(String beanName, Object singletonObject) { * synchronized (this.singletonObjects) { * this.singletonObjects.put(beanName, singletonObject); * this.singletonFactories.remove(beanName); * this.earlySingletonObjects.remove(beanName); * this.registeredSingletons.add(beanName); *} * /addSingleton(beanName, singletonObject); }}returnsingletonObject; }}Copy the code

Now let’s look at the getObject() method, and the comment says that in getObject() we’re actually calling createBean()

Let’s focus on the createBean() method;

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
Copy the code

The third parameter, the args array, represents the parameters needed to create the instance, either for the constructor or for the factory Bean, but note that during our initialization phase, args is null.

Look at the name of the class, we come to a new kind of AbstractAutowireCapableBeanFactory, mainly to the @autowired annotation into property values

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

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

	 // Make sure the Class in BeanDefinition is loadedClass<? > resolvedClass = resolveBeanClass(mbd, beanName);if(resolvedClass ! =null&&! mbd.hasBeanClass() && mbd.getBeanClassName() ! =null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}

		// Prepare method overrides.
		try {
       // Handles the lookup-method and replace-method configurations, which Spring collectively calls override method
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw newBeanDefinitionStoreException(...) ; }try {
			// Apply the post-processing before the bean is initialized. If the bean returned by the post-processing is not empty, it is returned directly
			// This class needs to be demonstrated in code
           / / here to perform the bean = applyBeanPostProcessorsBeforeInstantiation (targetType, beanName); Used in AOP, a proxy object can be returned
			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
			if(bean ! =null) {
				returnbean; }}catch (Throwable ex) {
			throw newBeanCreationException(.....) ; }try {
            / / key
			Call doCreateBean to create the bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			//log.....
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(......);
		}
	}
Copy the code

We continue with the doCreateBean() method:

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

		// Instantiate the bean.
		BeanWrapper instanceWrapper = null;
		if (mbd.isSingleton()) {
			instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
		}
		if (instanceWrapper == null) {
			/** * creates a bean instance and returns it wrapped in a BeanWrapper implementation class object. * createBeanInstance contains three ways to create bean instances: * 1. Create bean instances using factory methods * 2. Create bean instances using autowire by constructor * 3. Create a bean instance by using the no-argument constructor method * * If the bean configuration information is configured with lookup-method and replace-method, the bean instance is enhanced with CGLIB *. More on lookup-method and replace-method later. * /
			instanceWrapper = createBeanInstance(beanName, mbd, args);
		}
		finalObject bean = instanceWrapper.getWrappedInstance(); Class<? > beanType = instanceWrapper.getWrappedClass();if(beanType ! = NullBean.class) { mbd.resolvedTargetType = beanType; }/ / Suggestions to skip, involving interface: MergedBeanDefinitionPostProcessor
		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; }}// The following block of code is to solve the problem of loop dependency; We'll talk about that in a future article
		boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
				isSingletonCurrentlyInCreation(beanName));
		if (earlySingletonExposure) {
			if (logger.isDebugEnabled()) {
				//log....
			}
			addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
		}

		// Initialize the bean instance.
		Object exposedObject = bean;
		try {
			// Set properties, very important
       // This step is responsible for the attribute assembly, because the previous instance was only instantiated, not set, this is set
			populateBean(beanName, mbd, instanceWrapper);
			// Execute the post-processor, where AOP is done
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

		/ /... Omitted some unimportant code

		// Register bean as disposable.
		try {
			registerDisposableBeanIfNecessary(beanName, bean, mbd);
		}
		catch (BeanDefinitionValidationException ex) {
			throw newBeanCreationException(.....) ; }return exposedObject;
	}
Copy the code

The above code focuses on the createBeanInstance() method;

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure the class is loadedClass<? > beanClass = resolveBeanClass(mbd, beanName);Spring allows access to non-public classes by default. * /
		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 the factory method is not empty, then through the factory method to build bean object * this way to build bean can write a demo to try * source code does not do in-depth analysis, interested students can discuss with me privately */
		if(mbd.getFactoryMethodName() ! =null)  {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		/** * This is a Shortcut, what does it mean? * You can use Shortcut when building the same bean multiple times, * that is, you don't need to deduce which way to construct the bean each time * for example, when building the same Prototypebean multiple times, Can go the Shortcut here * resolved here and MBD constructorArgumentsResolved will be the first time in the bean instance is set in the process of *; * /
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if(mbd.resolvedConstructorOrFactoryMethod ! =null) {
					resolved = true;
					// If the constructor parameters are parsed, you must instantiate the constructor with a parameterautowireNecessary = mbd.constructorArgumentsResolved; }}}if (resolved) {
			if (autowireNecessary) {
				// Construct the bean object by means of constructor auto-assembly
				return autowireConstructor(beanName, mbd, null.null);
			}
			else {
				// through the default no-argument constructor
				returninstantiateBean(beanName, mbd); }}// Candidate constructors for autowiring?
		// It is up to the post-processor to decide which constructors to returnConstructor<? >[] 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.
		// Use the default no-argument constructor for initialization
		return instantiateBean(beanName, mbd);
	}
Copy the code

Let’s see how a no-argument construct instantiates an object, okay

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
		try {
			Object beanInstance;
			final BeanFactory parent = this;
			if(System.getSecurityManager() ! =null) {
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
				/ / getInstantiationStrategy class instantiation strategy ()
				// The default is to get a reflected instantiation policy
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			// Wrap it up for return
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); }}Copy the code

The key codes are:

beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);

After getting the reflected instantiation policy, go to the Instantiate method:

public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
		// Don't override the class with CGLIB if no overrides.
		// Check whether lookup-method or replace-method is configured in the bean configuration
		// If configured, use CGLIB to build bean objects
		if(! bd.hasMethodOverrides()) { Constructor<? > constructorToUse;synchronized(bd.constructorArgumentLock) { constructorToUse = (Constructor<? >) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {
					finalClass<? > 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 {
							// Get a no-parameter construct
							constructorToUse =	clazz.getDeclaredConstructor();
						}
						/ / to resolvedConstructorOrFactoryMethod assigned values here
						bd.resolvedConstructorOrFactoryMethod = constructorToUse;
					}
					catch (Throwable ex) {
						throw new BeanInstantiationException(clazz, "No default constructor found", ex); }}}/ / instantiate
			return BeanUtils.instantiateClass(constructorToUse);
		}
		else {
			// Must generate CGLIB subclass.
			returninstantiateWithMethodInjection(bd, beanName, owner); }}Copy the code

Go to the instantiateClass method to instantiate:

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {
		Assert.notNull(ctor, "Constructor must not be null");
		try {
			// Set the constructor to accessible
			ReflectionUtils.makeAccessible(ctor);
			// reflection creates objects
			return (KotlinDetector.isKotlinType(ctor.getDeclaringClass()) ?
					KotlinDelegate.instantiateClass(ctor, args) : ctor.newInstance(args));
		}
Copy the code

Here it’s easy to instantiate using reflection Ctor.newinstance (args); Here we take the instantiated Bean and return it to:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

To set properties and handle dependencies

protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
   // All the attributes of the bean instance are there
   PropertyValues pvs = mbd.getPropertyValues();

   if (bw == null) {
      if(! pvs.isEmpty()) {throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return; }}// At this point, the bean has been instantiated (through the factory method or constructor), but the property setting has not started yet,
   / / InstantiationAwareBeanPostProcessor implementation class can be to make state changes to your bean here,
   // I haven't found a practical use for it either, so let's ignore it for now
   boolean continueWithPropertyPopulation = true;
   if(! mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // If false is returned, no further attribute setting is required and no further BeanPostProcessor processing is required
            if(! ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation =false;
               break; }}}}if(! continueWithPropertyPopulation) {return;
   }

   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

      // Find all attribute values by name. If it is a bean dependency, initialize the dependent bean first. Recording dependencies
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }

      // Assemble by type. complicated
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      }

      pvs = newPvs;
   }

   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   booleanneedsDepCheck = (mbd.getDependencyCheck() ! = RootBeanDefinition.DEPENDENCY_CHECK_NONE);if(hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw,  mbd.allowCaching);if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               / / there is a very useful BeanPostProcessor enter here: AutowiredAnnotationBeanPostProcessor
               // Set the values of @autowired and @Value annotations. There is a lot of information here, but this article won't go into it
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return; }}}}if(needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); }}// Set the property value of the bean instance
   applyPropertyValues(beanName, mbd, bw, pvs);
}
Copy the code

After property injection is complete, various callbacks are handled immediately:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
		if(System.getSecurityManager() ! =null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
      // If the bean implements the BeanNameAware, BeanClassLoaderAware, or BeanFactoryAware interface, callback
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null| |! mbd.isSynthetic()) {// Execute the beFOR for the post-processing
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// Execute the init method in the bean's declaration cycle callback
      // Or if the bean implements the InitializingBean interface, call the afterPropertiesSet() 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()) {// Execute the afterhandler's after method
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
Copy the code

Both callbacks to BeanPostProcessor happen here, but init-method is handled in between

So that’s the whole initialization process; Draw a diagram below explain the whole process of finishBeanFactoryInitialization method:

Because the image is a little bit big, I made it smaller, so if you don’t see the image clearly, you can pull out the address and view it in the browser;

Spring source code with Chinese annotations

Blog summary

Use blogs for better viewing