• Spring实例化Bean流程解析


    注:本文仅解释其实例化过程,属性注入、循环依赖等下一篇解析。

    首先我们查看示例的代码

    Demo1.java:

    @Component("demo1")
    public class Demo1 {
    }
    

    Main.java:

    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
    applicationContext.register(AppConfig.class);
    applicationContext.refresh();
    

    AppConfig里面就是一个配置类,就加入了扫描包的配置。

    回顾Spring的创建流程

    我们还是得先回顾Spring的创建流程:

    可以看到,我们创建对象的操作是在refresh的finishBeanFactoryInitialization方法当中。

    那么我们就进去此方法:

    finishBeanFactoryInitialization(beanFactory);

    这里面唯一需要我们注意的就是第一个if了,可以让我们自定义类型类型转化器。

    实例化Bean的方法为最后一行代码的调用。

    beanFactory.preInstantiateSingletons();

    注意此处beanFactory为org.springframework.beans.factory.support.DefaultListableBeanFactory

    这个方法的代码:

    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.
    		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);/*此处拿到当前容器中所有的bd的name*/
    
    		// Trigger initialization of all non-lazy singleton beans...
    		for (String beanName : beanNames) {
    			/*
    			* 此处合并父BeanDefinition
    			* 在xml中可以配置一个Bean的parent,比如当前有一个Bean的定义如下
    			* <bean id="demo1" class="xxxx.Demo1" "></bean>
    			* 然后我们当前的Bean现在是这样的:
    			* <bean id="demo1Children" parent="demo1"></bean>
    			* 那么当现在循环的beanName为demo1Children的时候,需要合并父类的Bean的一些信息.
    			* 此处的getMergedLocalBeanDefinition就是干这个事情的
    			* */
    			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
    			/*
    			* 此处进入if需要的条件:
    			* 	1、当前bean不是抽象的
    			* 	2、当前bean是单例的
    			* 	3、当前类不是懒加载的
    			* 如果都成立才会进入if,如果不成立的话,那么此处则不会去实例化这个bean
    			* */
    			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
    				/*
    				* 如果是FactoryBean的话,则会单独处理,否则进入else,此处的需要去了解具体的factoryBean的内容,才知道此处做的处理是干的什么事情
    				*  */
    				if (isFactoryBean(beanName)) {
    					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
    					if (bean instanceof FactoryBean) {
    						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 {
    					/* 不是FactoryBean则进入此方法, */
    					getBean(beanName);
    				}
    			}
    		}
    
    		// Trigger post-initialization callback for all applicable beans...
    		for (String beanName : beanNames) {
    			Object singletonInstance = getSingleton(beanName);
    			if (singletonInstance instanceof SmartInitializingSingleton) {
    				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
    				if (System.getSecurityManager() != null) {
    					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    						smartSingleton.afterSingletonsInstantiated();
    						return null;
    					}, getAccessControlContext());
    				}
    				else {
    					smartSingleton.afterSingletonsInstantiated();
    				}
    			}
    		}
    	}
    

    1、首先拿到当前容器中所有的bean名称,这些名称包含已经配置解析出来的所有类。

    2、循环这些beanName

    ​ 1):getMergedLocalBeanDefinition合并父BeanDefinition,意思就是如果当前的bean并不是指定class,而是直接指定了parent,这种情况下需要去将parent的信息拿出来,当然这个东西用的很少,且只能在xml中配置

    ​ 2):判断当这个类不是抽象的,且必须为单例,且不是懒加载,那么则进入代码操作,否则认为其不是一个单例Bean,则此时不应该去实例化

    ​ 3):进入if后判断是否为FactoryBean,这个判断的依据就是,如果当前Bean的name为xxx,那么如果容器中存在&xxx的beanName,那么说明当前的这个Bean是一个FactoryBean,需要去调用其实现的方法获取bean,如果不是FactoryBean,则进入else直接getBean(name)。我们这里重点并不是解释FactoryBean,我们解释的是普通的Bean去实例化。

    ​ 4):在看else的getBean之前,我们先看最后的那个循环,那个循环干的事情就是判断当前的这个Bean是否实现了SmartInitializingSingleton接口,如果实现了则去调用其实现的回调接口

    ​ 5):现在我们进入其else的getBean方法。

    getBean(beanName)

    @Override
    public Object getBean(String name) throws BeansException {
       return doGetBean(name, null, null, false);
    }
    

    这个没什么好说的,进入doGetBean

    return doGetBean(name, null, null, false);

    protected <T> T doGetBean(
    			String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    			throws BeansException {
    		/* 此处需要处理FactoryBean的情况,如果是FactoryBean的话,此处的BeanName为&xxxx,此处需要将&去掉 */
    		String beanName = transformedBeanName(name);
    		Object bean;
    
    		/*
    		* 去当前容器中获取实例化好的Bean,如果bean不为空,则直接返回了,如果为空,则需要去实例化,进入else
    		*  */
    		// Eagerly check singleton cache for manually registered singletons.
    		Object sharedInstance = getSingleton(beanName);
    		if (sharedInstance != null && args == null) {
    			if (logger.isDebugEnabled()) {
    				if (isSingletonCurrentlyInCreation(beanName)) {
    					logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
    							"' that is not fully initialized yet - a consequence of a circular reference");
    				}
    				else {
    					logger.debug("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.
    			/*
    			* 以下注释待审查,不一定正确:
    			* 	判断当前类是否为原型的,也就是非单例的,如果是则报错.
    			* 	在我们前面for循环的地方已经判断了,只有当是单例的时候才会进入循环内部进行操作,那么此处再判断一次,更加的严谨.
    			* */
    			if (isPrototypeCurrentlyInCreation(beanName)) {
    				throw new BeanCurrentlyInCreationException(beanName);
    			}
    
    			// Check if bean definition exists in this factory.获取beanFactory的父类,一般我们没有设置则此处为空,
    			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 {
    					// No args -> delegate to standard getBean method.
    					return parentBeanFactory.getBean(nameToLookup, requiredType);
    				}
    			}
    			/* 将当前beanName存放至[正在创建中的Bean]的集合中去. */
    			if (!typeCheckOnly) {
    				markBeanAsCreated(beanName);
    			}
    
    			try {
    				/*
    				* 合并父BeanDefinition,这个在前面说过:
    				* 	org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons
    				*  */
    				RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    				/* 如果当前类是抽象的,则抛出异常 */
    				checkMergedBeanDefinition(mbd, beanName, args);
    
    				// Guarantee initialization of beans that the current bean depends on.
    				/* 处理解析@DependsOn */
    				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()) {
    					sharedInstance = getSingleton(beanName, () -> {
    						try {
    							/* 进入到这个方法当中去创建bean */
    							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()) {
    					。。。。。。。。
    				}
    
    				else {
    					。。。。。。。
    				}
    			}
    			catch (BeansException ex) {
    				cleanupAfterBeanCreationFailure(beanName);
    				throw ex;
    			}
    		}
    
    		// Check if required type matches the type of the actual bean instance.
    		。。。。。。
    		return (T) bean;
    	}
    

    这个代码太长了,我们一段一段的解释,不重要的代码此处。。。。代替

    来看第一段:

    /* 此处需要处理FactoryBean的情况,如果是FactoryBean的话,此处的BeanName为&xxxx,此处需要将&去掉 */
    String beanName = transformedBeanName(name);
    Object bean;
    
    /*
    		* 去当前容器中获取实例化好的Bean,如果bean不为空,则直接返回了,如果为空,则需要去实例化,进入else
    		*  */
    // Eagerly check singleton cache for manually registered singletons.
    Object sharedInstance = getSingleton(beanName);
    if (sharedInstance != null && args == null) {
        if (logger.isDebugEnabled()) {
            if (isSingletonCurrentlyInCreation(beanName)) {
                logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
                             "' that is not fully initialized yet - a consequence of a circular reference");
            }
            else {
                logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
            }
        }
        bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
    }
    

    1、首先transformedBeanName,这个方法就是如果beanName.startWith("&"),那么则去除&

    2、然后看下一行的Object sharedInstance = getSingleton(beanName);

    ​ 这个方法的核心代码如下:

    protected Object getSingleton(String beanName, boolean allowEarlyReference) {
    		Object singletonObject = this.singletonObjects.get(beanName);
    		if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
    			synchronized (this.singletonObjects) {
    				singletonObject = this.earlySingletonObjects.get(beanName);
    				if (singletonObject == null && allowEarlyReference) {
    					ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
    					if (singletonFactory != null) {
    						singletonObject = singletonFactory.getObject();
    						this.earlySingletonObjects.put(beanName, singletonObject);
    						this.singletonFactories.remove(beanName);
    					}
    				}
    			}
    		}
    		return singletonObject;
    	}
    

    这里的this.singletonObjects为(private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);),这个map就是存放的单例对象,其实这里也有一个对ioc容器的理解,从微观上来看,这个map就是ioc容器,从宏观上来看,ioc则是整个spring的BeanFactory(org.springframework.beans.factory.support.DefaultListableBeanFactory),这也是一种对于容器自己的理解。回到代码里面,这里从map中获取这个Object,如果Object不为空,则直接返回来,如果Object为空,且正在创建过程中(isSingletonCurrentlyInCreation就是判断是否正在创建过程中的方法,这里面就是判断map中是否存在当前这个Object),那么进入if,if中从缓存map(this.earlySingletonObjects)中拿到Object,如果Object为空,则从另外一个缓存map中拿到该Object,如果Object存在,则赋值singletonFactory并且将该Object放入this.earlySingletonObjects缓存Map中,并从this.singletonFactories缓存中删除,这个东西涉及到后面的属性注入,此处我们先知道这个,如随笔开头所说,这个问题下篇会详细解释,这篇随笔里面我们不考虑其属性注入循环依赖,先搞清楚其实例化过程,因为网上大部分文章都对此属性注入一路直接说下去,很容易看懵,我们这里循序渐进。

    3、当调用方法获取到的sharedInstance 不为空,则将其bean赋值,且不进入else,然后就直接return这个bean。

    再来看第二段,也就是else里面:

    /*
    * 	检测是否存在循环依赖,如果是,则报错
    * */
    if (isPrototypeCurrentlyInCreation(beanName)) {
        throw new BeanCurrentlyInCreationException(beanName);
    }
    
    // Check if bean definition exists in this factory.获取beanFactory的父类,一般我们没有设置则此处为空,
    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 {
            // No args -> delegate to standard getBean method.
            return parentBeanFactory.getBean(nameToLookup, requiredType);
        }
    }
    /* 将当前beanName存放至[正在创建中的Bean]的集合中去. */
    if (!typeCheckOnly) {
        markBeanAsCreated(beanName);
    }
    

    1、首先的那个if,isPrototypeCurrentlyInCreation就是判断是否存在循环依赖,如果存在则报错。

    2、然后getParentBeanFactory,这个方法是获取我们设置的父BeanFactory,一般我们没有设置,if不会进去,直接忽略。

    3、将当前的beanName存放至map当中,这个map代表着当前正在创建的bean

    再来看第三段:

    try {
        /*
    	* 合并父BeanDefinition,这个在前面说过:
    	* 	org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons
    	*  */
        RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
        /* 如果当前类是抽象的,则抛出异常 */
        checkMergedBeanDefinition(mbd, beanName, args);
    
        // Guarantee initialization of beans that the current bean depends on.
        /* 处理解析@DependsOn */
        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);
                }
            }
        }
    

    1、首先getMergedLocalBeanDefinition是合并父BeanDefinition,我们前面说了这里就不累赘。

    2、如果当前类是抽象的,则抛出异常

    3、解析@DependsOn的情况

    再来看第四段:

    // Create bean instance.如果是单例的话
    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, () -> {
            try {
                /* 进入到这个方法当中去创建bean */
                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);
    }
    

    判断当前类是否为单例,是则进入单例的实例化方法,这个if的else这些其实就是如果当前类不是单例,是多例这种情况的实例化,所以前面我“。。。。”给代替了,我们主要看单例的。

    1、进入getSingleton方法:

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "Bean name must not be null");
        synchronized (this.singletonObjects) {
            /* 如果容器中存在bean,则直接返回,否则进入if */
            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 + "'");
                }
                /*
    				* 标志当前单例bean正在创建当中,如果当前bean已经在创建当中了,则抛出异常
    				* 这里判断是否正在创建和标志创建中的依据是一个Set集合
    				*  */
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<>();
                }
                try {
                    /* 调用其回调接口,这个singleFactory是传进来的接口参数 */
                    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;
        }
    }
    

    1、Object singletonObject = this.singletonObjects.get(beanName);从容器中拿一次,如果存在则直接返回了

    2、beforeSingletonCreation(beanName);做一个重复创建的校验

    3、singletonObject = singletonFactory.getObject();,这个singleFactory.getObject其实就是我们传进来那个参数:

    所以我们进入createBean方法当中去。

    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 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<?> 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.
    			/*
    			* 如果有这种需求:
    			* 	我们希望指定beanName的bean不通过spring实例化,而是我们直接实例化,并且还需要将其放入spring容器当中去,那么这个功能就是在此处实现的.
    			* 调用我们实现了InstantiationAwareBeanPostProcessor接口的类的回调方法.
    			* 这个接口中需要实现这个方法:
    			* 	postProcessBeforeInstantiation
    			* spring会将当前的beanName传入该方法,如果该方法返回的Object不为空, 那么Spring就会认为这个Object就是实例化完成的Object,则容器存放的Object就是当前的这个Object
    			*  */
    			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 {
    			/* 创建Bean */
    			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    			if (logger.isDebugEnabled()) {
    				logger.debug("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);
    		}
    	}
    

    1、Class<?> resolvedClass = resolveBeanClass(mbd, beanName);,拿到当前的Class对象

    2、mbdToUse.prepareMethodOverrides();去解析方法覆盖,这个用得很少,我也不是很清楚,但是这个肯定不难,可以百度看一下

    3、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);指定某些类不通过Spring去实例化,而由我们自己实例化,具体可看一下上面的注释,下面看一下这个方法实际干的事情

    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) {
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    

    applyBeanPostProcessorsBeforeInstantiation方法:

    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    		for (BeanPostProcessor bp : getBeanPostProcessors()) {
    			if (bp instanceof InstantiationAwareBeanPostProcessor) {
    				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    				if (result != null) {
    					return result;
    				}
    			}
    		}
    		return null;
    	}
    

    这里面去执行实现InstantiationAwareBeanPostProcessor的BeanPostProcessor其回调方法postProcessBeforeInstantiation,且如果方法返回的Object不为空,则直接返回了。

    然后回到第3步的applyBeanPostProcessorsAfterInitialization中,这里面代码就不贴了,因为这种Object不会执行后续的逻辑,所以就直接这里去执行其BeanPostProcessor的回调了.

    4、如果上面的Object bean仍然为空的话,那么则会去调用doCreateBean方法创建Bean,然后返回这个Bean,我们下面看看这个doCreateBean方法。

    	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) {
    			/* 这里实际上是去创建Bean了 */
    			instanceWrapper = createBeanInstance(beanName, mbd, args);
    		}
    		Object bean = instanceWrapper.getWrappedInstance();
    		Class<?> beanType = instanceWrapper.getWrappedClass();
    		if (beanType != NullBean.class) {
    			mbd.resolvedTargetType = beanType;
    		}
    

    此处截取了doCreateBean的上半部分代码,下半部分代码是用于做代理,或其他回调的,本篇不涉及。

    5、进入createBeanInstance方法中:

    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    		// Make sure bean class is actually resolved at this point.见名知意,此处是去拿到Class对象
    		Class<?> beanClass = resolveBeanClass(mbd, beanName);
    		/* 如果此处我们的构造器全都是私有的,那么则代表根本无法通过构造器注入了,这里就是判断,如果构造器全部都无法访问,那么则抛出异常提示无法创建bean */
    		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());
    		}
    		/*创建Bean的回调,暂时也不知道是干嘛用的*/
    		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    		if (instanceSupplier != null) {
    			return obtainFromSupplier(instanceSupplier, beanName);
    		}
    		/*
    		* factoryName:
    		* 	如果我们在xml中定义bean如下:
    		* 	<bean id='xxxx' class='xxx.Demo1' factory-method='creator'></bean>
    		* 	那么我们创建这个bean的方式就不再是通过spring去实例化,而是通过调用creator这个静态方法去获取该bean的对象.
    		* 	那么如果这种情况:
    		* 		当我们的mbd的class类型为xxx.Demo1,然后但我们creator返回的Object的类型为xxx.Demo2,那么当前这个mdb的class值也会相应的改变为xxx.Demo2
    		* 		且我们获取这个Object到其他类的时候,不能使用Class类型的方式去注入,只能使用xxx名称,或者Demo2.class的类型去注入.
    		* 		相当于是修改了mbd的class属性,而没有修改其id属性
    		*  */
    		if (mbd.getFactoryMethodName() != null) {
    			return instantiateUsingFactoryMethod(beanName, mbd, args);
    		}
    
    		// Shortcut when re-creating the same bean...
    		/*
    		* 快捷操作:
    		* 	如果当这个bean是原型的时候,当第二次来调用getBean的时候则不会再去判断需要使用哪个构造方法.
    		* 	而是在第一次getBean的时候记录其当前使用的构造器方法,然后第二次getBean的时候就不用再去挨个的判断,节省时间相当于是
    		* */
    		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?
    		/**
    		 * 此处去获取当前类中可用的有参构造器:
    		 *  注意这个方法不会去获取无参构造器,如果是无参构造器的话,那么直接去调用instantiateBean方法,这个方法里面会直接去调用无参的构造器
    		 *  如果类中包含有参构造器,那么这个determineConstructorsFromBeanPostProcessors方法则会获取到,并且调用autowireConstructor方法对这个构造器进行调用创建对象
    		 */
    		Constructor<?>[] 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.
    		/* 直接调用无参构造器 */
    		return instantiateBean(beanName, mbd);
    	}
    

    ​ 1):首先是对当前类的构造器进行一个校验,比如有可用的构造器。

    ​ 2):创建Bean的回调

    ​ 3):如果指定了factoryMethod,那么则去调用这个factoryMethod来实例化本类

    ​ 4):创建类的快捷操作,主要是当类是原型的时候使用

    ​ 5):去获取该类中可用的构造器

    ​ determineConstructorsFromBeanPostProcessors方法:返回带参数的构造器,如果该构造器列表不为空,则通过autowireConstructor去调用构造方法获取到实例。

    ​ 如果上面的方法获取构造器为空,那么则说明当前只有默认构造器可用,那么则去调用instantiateBean方法通过默认构造器去实例化对象。

    。。。

  • 相关阅读:
    JAVA Unsafe类
    进程通信的五种普通方法
    监控API的实现 周末补
    INLINE HOOK 简单实现
    跨域资源请求方式
    在博客园放入“可运行”javascript代码
    一些学习资源
    XXE篇-本着就了解安全本质的想法,尽可能的用通俗易懂的语言去解释安全漏洞问题
    Mongodb注入
    SSRF篇-本着就了解安全本质的想法,尽可能的用通俗易懂的语言去解释安全漏洞问题
  • 原文地址:https://www.cnblogs.com/daihang2366/p/15316822.html
Copyright © 2020-2023  润新知