Preparatory operations before spring instantiation

Pre-operation of spring initialization

Before spring actually starts to instantiate, there will be some operations. This note is mainly to record the processing logic before actually calling the post processor.

The instantiation of spring is done by calling a series of post processors

As mentioned earlier, the operation of spring on the bean is completed in the refresh method, and finishBeanFactoryInitialization is to instantiate the bean in the beanDefinitionMap collection

org.springframework.context.support.AbstractApplicationContext#refresh
 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization
  org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons

In this method, the following operations are mainly completed:

* 1.遍历所有的beanDefinitionName,完成合并bean的操作
* 2.如果当前bean是单实例的、非懒加载的、非抽象bean,就调用bean的后置处理器 完成实例化的操作
* 3.在所有bean都实例化完成之后,调用实现了SmartInitializingSingleton接口的bean对象,完成org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()方法的调用
@Override
	public void preInstantiateSingletons() 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.
		/**
		 * 在将beanDefinition存入BeanDefinitionMap的同时,会将beanName存入到一个list集合中
		 * 这里直接从beanDefinitionNames这个集合中,获取所有要实例化的bean的name
		 */
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//触发所有非延迟加载单实例bean的加载,加载的过程就是调用getBean()方法  上面获取到的是所有的beanName
		for (String beanName : beanNames) {
    
    
			/**
			 * 合并父类beanDefinition;在前面初始化bean的时候,就已经合并了,这里是再判断一次,如果当前bean没有合并,就合并;如果已经合并了,就直接从
			 * 对应的map集合中取出合并之后的beanDefinition
			 *
			 * 之所以要做beanDefinition的merge操作,是因为有些beanDefinition是RootBeanDefinition的子类,如果直接用子BeanDefinition去实例化,可能会有问题
			 * 因为一个子BeanDefinition可以继承父beanDefinition,一些共性的信息可以放到父BeanDefinition中,所以,在对bean进行初始化的时候,都要对相应的beanDefinition进行合并的操作,得到RootBeanDefinition;比如:
			 *  RootBeanDefinitionA设置需要注入name属性
			 *  BeanDefinitionB设置需要注入type属性,再设置BeanDefinitionB 继承RootBeanDefinitionA,假如在这里不合并rootBeanDefinitionA,那么B这个bd需要注入的属性就只有type,不会有name,那也就不是我们想要的bd了;所以这里要把子bd的属性合并到新的RootBeanDefinition中
			 *
			 *  并且,spring在初始化bean的过程中,会对bd进行一些校验(比如:是否是单实例的,是否是抽象的等);所以:这里要先把bd进行合并,获取到父类的bd属性信息
			 */
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			// 非抽象、非懒加载、单实例的bean
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    
    
				//判断当前bean是否是beanFactory;如果是factoryBean,在beanName前面加上 &
				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 {
    
    
					//这里是去完成bean的实例化
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		/**
		 * 这里应该也算是spring提供的一个扩展点之一
		 * 在所有的bean都实例化完成之后,会调用org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
		 * 来完成程序员的一些业务逻辑操作
		 */
		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();
				}
			}
		}
	}

The core operation is the getBean() method. In the getBean() method, the org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean method will be called

Guess you like

Origin blog.csdn.net/CPLASF_/article/details/108179576