spring实例化前的准备操作

spring初始化的前置操作

spring真正开始实例化之前,会有一些操作,该笔记,主要来记录真正调用后置处理器之前的处理逻辑

spring的实例化,是通过调用一系列的后置处理器来完成

前面有说到过,spring对bean的操作,是在refresh方法中完成的,finishBeanFactoryInitialization是对beanDefinitionMap集合中的bean进行实例化的

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

在这个方法中,主要完成了以下几个操作:

* 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();
				}
			}
		}
	}

核心的操作是getBean()方法,在getBean()方法中,会调用到org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean方法

猜你喜欢

转载自blog.csdn.net/CPLASF_/article/details/108179576