• Spring源码分析之IOC的三种常见用法及源码实现(三)


    上篇文章我们分析了AnnotationConfigApplicationContext的构造器里refresh方法里的invokeBeanFactoryPostProcessors,了解了@Component和@Bean的原理等,invokeBeanFactoryPostProcessors还没分析完,后面还有部分代码,继续看

    refresh里的invokeBeanFactoryPostProcessors剩余代码

    首先看看整体

    public static void invokeBeanFactoryPostProcessors(
    			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
    		Set<String> processedBeans = new HashSet<String>();
    
    		if (beanFactory instanceof BeanDefinitionRegistry) {
    			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
    			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
    					new LinkedList<BeanDefinitionRegistryPostProcessor>();
    
    			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    					BeanDefinitionRegistryPostProcessor registryPostProcessor =
    							(BeanDefinitionRegistryPostProcessor) postProcessor;
    					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
    					registryPostProcessors.add(registryPostProcessor);
    				}
    				else {
    					regularPostProcessors.add(postProcessor);
    				}
    			}
    
    			// Do not initialize FactoryBeans here: We need to leave all regular beans
    			// uninitialized to let the bean factory post-processors apply to them!
    			// Separate between BeanDefinitionRegistryPostProcessors that implement
    			// PriorityOrdered, Ordered, and the rest.
    			String[] postProcessorNames =
    					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    
    			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
    			for (String ppName : postProcessorNames) {
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    			registryPostProcessors.addAll(priorityOrderedPostProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);
    
    			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
    			for (String ppName : postProcessorNames) {
    				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    			sortPostProcessors(beanFactory, orderedPostProcessors);
    			registryPostProcessors.addAll(orderedPostProcessors);
    			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);
    
    			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
    			boolean reiterate = true;
    			while (reiterate) {
    				reiterate = false;
    				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
    				for (String ppName : postProcessorNames) {
    					if (!processedBeans.contains(ppName)) {
    						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
    						registryPostProcessors.add(pp);
    						processedBeans.add(ppName);
    						pp.postProcessBeanDefinitionRegistry(registry);
    						reiterate = true;
    					}
    				}
    			}
    
    			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
    			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
    			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
    		}
    
    		else {
    			// Invoke factory processors registered with the context instance.
    			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
    		}
    
    		// Do not initialize FactoryBeans here: We need to leave all regular beans
    		// uninitialized to let the bean factory post-processors apply to them!
    		String[] postProcessorNames =
    				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
    
    		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
    		// Ordered, and the rest.
    		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    		List<String> orderedPostProcessorNames = new ArrayList<String>();
    		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
    		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);
    			}
    		}
    
    		// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    		sortPostProcessors(beanFactory, priorityOrderedPostProcessors);
    		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    
    		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    		for (String postProcessorName : orderedPostProcessorNames) {
    			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		sortPostProcessors(beanFactory, orderedPostProcessors);
    		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    
    		// Finally, invoke all other BeanFactoryPostProcessors.
    		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
    		for (String postProcessorName : nonOrderedPostProcessorNames) {
    			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    		}
    		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    
    		// Clear cached merged bean definitions since the post-processors might have
    		// modified the original metadata, e.g. replacing placeholders in values...
    		beanFactory.clearMetadataCache();
    	}
    

    上次是讲了里面的invokeBeanFactoryPostProcessors,里面有很多次invokeBeanFactoryPostProcessors调用,后面这么多重复调用是干嘛呢?

    其实在debug的时候并没有执行,这里体现的spring的一个理念 开放接口,只要当我们覆写了它的接口的时候这些后面的invokeBeanFactoryPostProcessors就会执行,这也是为什么这里创建了好几个LinkedList把不同的加到不同的LinkedList中,这样分类就是为了去区分你覆写的接口然后去调用你写的接口里的代码。

    具体的说:看里面注释:

    // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
    			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
    			for (String ppName : postProcessorNames) {
    				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
    					processedBeans.add(ppName);
    				}
    			}
    

    First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.

    翻译:首先,调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors。

    // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
    

    翻译://接下来,调用实现Ordered接口的BeanDefinitionRegistryPostProcessors。

    总的来说,区分有没有实现Ordered接口然后再根据排序调用。

    从getBean()说起

    getBean方法源码如下:

        public Object getBean(String name) throws BeansException {
            this.assertBeanFactoryActive();
            return this.getBeanFactory().getBean(name);
        }
    

    第一行只是判断beanFactory是否激活了,里面只是if else判断一下 关闭了咋抛异常。我们看重点第二局的getBean源码:

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

    一看到doXXX就知道这是spring的习惯doXXX就会有真正的主逻辑了,进去:

    	protected <T> T doGetBean(
    			final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
    			throws BeansException {
    
    		final String beanName = transformedBeanName(name);
    		Object bean;
    
    		// 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.
    			if (isPrototypeCurrentlyInCreation(beanName)) {
    				throw new BeanCurrentlyInCreationException(beanName);
    			}
    
    			// Check if bean definition exists in this factory.
    			BeanFactory parentBeanFactory = getParentBeanFactory();
    			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    				// Not found -> check parent.
    				String nameToLookup = originalBeanName(name);
    				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);
    				}
    			}
    
    			if (!typeCheckOnly) {
    				markBeanAsCreated(beanName);
    			}
    
    			try {
    				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    				checkMergedBeanDefinition(mbd, beanName, args);
    
    				// Guarantee initialization of beans that the current bean depends on.
    				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);
    						getBean(dep);
    					}
    				}
    
    				// Create bean instance.
    				if (mbd.isSingleton()) {
    					sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
    						@Override
    						public Object getObject() throws BeansException {
    							try {
    								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()) {
    					// It's a prototype -> create a new instance.
    					Object prototypeInstance = null;
    					try {
    						beforePrototypeCreation(beanName);
    						prototypeInstance = createBean(beanName, mbd, args);
    					}
    					finally {
    						afterPrototypeCreation(beanName);
    					}
    					bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    				}
    
    				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, new ObjectFactory<Object>() {
    							@Override
    							public Object getObject() throws BeansException {
    								beforePrototypeCreation(beanName);
    								try {
    									return createBean(beanName, mbd, args);
    								}
    								finally {
    									afterPrototypeCreation(beanName);
    								}
    							}
    						});
    						bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
    					}
    					catch (IllegalStateException ex) {
    						throw new BeanCreationException(beanName,
    								"Scope '" + scopeName + "' is not active for the current thread; consider " +
    								"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
    								ex);
    					}
    				}
    			}
    			catch (BeansException ex) {
    				cleanupAfterBeanCreationFailure(beanName);
    				throw ex;
    			}
    		}
    
    		// Check if required type matches the type of the actual bean instance.
    		if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
    			try {
    				return getTypeConverter().convertIfNecessary(bean, requiredType);
    			}
    			catch (TypeMismatchException ex) {
    				if (logger.isDebugEnabled()) {
    					logger.debug("Failed to convert bean '" + name + "' to required type '" +
    							ClassUtils.getQualifiedName(requiredType) + "'", ex);
    				}
    				throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
    			}
    		}
    		return (T) bean;
    	}
    

    doGetBean的transformedBeanName

    超级长的一个方法,慢慢分析,第一行是transformedBeanName方法获取名字,看看它是怎么获取名字的,点开源码:

    	protected String transformedBeanName(String name) {
    		return canonicalName(BeanFactoryUtils.transformedBeanName(name));
    	}
    

    看来是两次转换,先看第一层BeanFactoryUtils.transformedBeanName(name):

    	public static String transformedBeanName(String name) {
    		Assert.notNull(name, "'name' must not be null");
    		String beanName = name;
    		while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
    			beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
    		}
    		return beanName;
    	}
    

    这个BeanFactory.FACTORY_BEAN_PREFIX实际上是个"&"符号,这里就是判断下是不是工厂Bean,把利用while循环把开头的&符号都去掉。

    然后我们看第二层名字转换:

        public String canonicalName(String name) {
            String canonicalName = name;
    
            String resolvedName;
            do {
                resolvedName = (String)this.aliasMap.get(canonicalName);
                if (resolvedName != null) {
                    canonicalName = resolvedName;
                }
            } while(resolvedName != null);
    
            return canonicalName;
        }
    

    这里看样子是从aliasMap里取值,alias存着别名对应的真正容器的名字。然而你会发现这里居然是个do while循环,这是为什么?因为可能存在多重别名的情况,需要不断的取别名的真名,真名又对应的真名...取到最终的真名。

    ok去bean名字看完了,接下来看doGetBean那么长那么长的后面的代码,接下来来看下据说是SpringIOC中最核心的方法代码。

    doGetBean的getSingleton

    查看源码:

    	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 != NULL_OBJECT ? singletonObject : null);
    	}
    

    Ok,这里就是IOC大名鼎鼎的多级缓存(解决循环依赖)了,首先第一句是从singletonObjects里当map直接取,其实singletonObjects就是叫单例缓存池,是一个ConcurrentHashMap。

    实际上当我第一次打断点调试的时候,始终直接就从singletonObjects中取到了想要的对象,后面的if判断就不进去,最后return了 然后就结束了。

    然而多级缓存不会这么简单就拿到了,我们为什么直接能拿到呢?其实是已经调用过一次getBean了,调用过了的就直接缓存在singletonObjects了,所以我们这次可以直接拿到,可以研究下第一次是什么时候创建在里面的,其实是在上篇文章的构造器的refresh方法中。

    我们可以直接在getBean里打断点而不是从最简单那两句慢慢跳进去,就可以停留在第一次getBean的时候了。实际上后面那个if判断还是进不去,if还有第二个条件必须正在创建时才进去,此时return null,ok,这才是第一次执行的样子。

    然后就返回上层那个很长的doGetBean方法了

    回到doGetBean

    由于返回的是Null,所以我们进后面的else了

    else {
    			// Fail if we're already creating this bean instance:
    			// We're assumably within a circular reference.
    			if (isPrototypeCurrentlyInCreation(beanName)) {
    				throw new BeanCurrentlyInCreationException(beanName);
    			}
    			....
    

    这里是对原型模式发生循环依赖的异常抛出,因为这里现在是准备创建,然后这个判断发现也同时在创建,这明显发生了循环依赖,于是抛出。

    至于为什么原型模式不能解决循环,因为原型模式(也就是多例)没进行多级缓存。

    后面代码:

    			// Check if bean definition exists in this factory.
    			BeanFactory parentBeanFactory = getParentBeanFactory();
    			if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
    				// Not found -> check parent.
    				String nameToLookup = originalBeanName(name);
    				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);
    				}
    			}
    
    			if (!typeCheckOnly) {
    				markBeanAsCreated(beanName);
    			}
    
    

    这里判断是不是有父级bean工厂,有则从上级的getBean取。后面就是判断创建的标记,将指定的bean标记为已经创建(或将要创建)。

    继续doGetBean往后看:

    				final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    				checkMergedBeanDefinition(mbd, beanName, args);
    

    在以前xml配置bean的时候可以加一个abstract属性,表达这个bean是一个父类,然后配置别的bean的时候可以继承自它,实现复用。那么这里的这个代码getMergedLocalBeanDefinition,其实就是获取是不是有父类,然后把他自己和父类的信息合并到一起成RootBeanDefinition并返回。后面这个checkMergedBeanDefinition,打开源码:

    	protected void checkMergedBeanDefinition(RootBeanDefinition mbd, String beanName, Object[] args)
    			throws BeanDefinitionStoreException {
    
    		if (mbd.isAbstract()) {
    			throw new BeanIsAbstractException(beanName);
    		}
    	}
    

    其实就是检查是不是合并好了,如果还存在abstract的就抛出异常。继续doGetBean往后看:

    // Guarantee initialization of beans that the current bean depends on.
    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);
            getBean(dep);
        }
    }
    

    这个是和@DependsOn注解有关的,有时候有些的bean初始化之前的得先初始化另外一个Bean,就需要用到这个@DependsOn注解。

    而这里这个getDependsOn就是获取需要先加载的bean,然后遍历这些bean,其中那个if判断就是检查它依赖的bean会不会是它自己,这样就造成循环,就抛出异常。

    后面的registerDependentBean是注册依赖关系,就是把哪些依赖我 我依赖哪些,都存到map里去

    再后面的getBean就是把依赖的bean初始化,这段就讲完了,再在doGetBean里往后看:

    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                try {
                    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()) {
        // It's a prototype -> create a new instance.
        Object prototypeInstance = null;
        try {
            beforePrototypeCreation(beanName);
            prototypeInstance = createBean(beanName, mbd, args);
        }
        finally {
            afterPrototypeCreation(beanName);
        }
        bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
    }
    
    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, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    beforePrototypeCreation(beanName);
                    try {
                        return createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                }
            });
            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
        catch (IllegalStateException ex) {
            throw new BeanCreationException(beanName,
                    "Scope '" + scopeName + "' is not active for the current thread; consider " +
                            "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                    ex);
        }
    }
    

    看样子是根据bean的类型分三种情况,单例、原型、其它 进行获取。首先来看看单例的情况:

    doGetBean的创建单例Bean的情况

    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                try {
                    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);
    }
    

    打开第一行的getSingleton方法源码(getSingleton有多个重载实现):

    public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
        Assert.notNull(beanName, "'beanName' must not be null");
        synchronized (this.singletonObjects) {
            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 + "'");
                }
                beforeSingletonCreation(beanName);
                boolean newSingleton = false;
                boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
                if (recordSuppressedExceptions) {
                    this.suppressedExceptions = new LinkedHashSet<Exception>();
                }
                try {
                    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 != NULL_OBJECT ? singletonObject : null);
        }
    }
    

    这里还是先去单例缓存池去取,取得到直接返回,取不到就进if判断了。if里的第一个真正执行的代码是beforeSingletonCreation(beanName);可以点进去查看:

    protected void beforeSingletonCreation(String beanName) {
        if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
            throw new BeanCurrentlyInCreationException(beanName);
        }
    }
    

    其实就是一个判断,巧用了if的&&,主要是就是把beanName加到singletonsCurrentlyInCreation做个记号,告诉这里正在创建。之前第一次访问doGetBean里第一次访问getSingleton的时候就是因为这个记号,没有进if判断。

    后面就是开始创建bean,拿了个标记变量并且调用了传参进来的的singletonFactory的getObject方法。最后创建好了的话加入到单例缓存池(addSingleton(beanName, singletonObject);)和注册单例,都是一个map put就好了。这里主要就是getObject方法。就是之前这:

    if (mbd.isSingleton()) {
        sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                try {
                    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);
    }
    

    可以看出实际上是调用的createBean

    doGetBean的createBean

    打开源码:

    /**
    	 * Central method of this class: creates a bean instance,
    	 * populates the bean instance, applies post-processors, etc.
    	 * @see #doCreateBean
    	 */
    	@Override
    	protected Object createBean(String beanName, RootBeanDefinition mbd, 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<?> 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.
    			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);
    		}
    
    		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    		if (logger.isDebugEnabled()) {
    			logger.debug("Finished creating instance of bean '" + beanName + "'");
    		}
    		return beanInstance;
    	}
    

    首先是从整合的RootBeanDefinition中解析出Class类型,然后是准备方法覆写。

    后面这行代码就比较重要了:

    //Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.返回代理对象,但是在IOC这里时候暂时没有用,之后AOP会是核心。
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    

    这里是AOP的核心,留给之后文章讲。是在有切面的时候切面找出来并缓存。

    继续往后看,看到了doXXX,这又是到了spring真正逻辑操作的地方了。

    createBean的doCreateBean

    调用这个方法时把beanNaem和RootBeanDefinition等传进去了

    打开源码:

    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
        throws BeanCreationException {
    
        // Instantiate the bean.
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
        Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
        mbd.resolvedTargetType = beanType;
    
        // Allow post-processors to modify the merged bean definition.
        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.
        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, new ObjectFactory<Object>() {
                @Override
                public Object getObject() throws BeansException {
                    return getEarlyBeanReference(beanName, mbd, bean);
                }
            });
        }
    
        // Initialize the bean instance.
        Object exposedObject = bean;
        try {
            populateBean(beanName, mbd, instanceWrapper);
            if (exposedObject != null) {
                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<String>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                ".....);
                    }
                }
            }
        }
    
        // Register bean as disposable.
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
    
        return exposedObject;
    }
    

    其中,调用instantiateUsingFactoryMethod是基于工厂方法去创建,autowireConstructor是根据构造器去创建的 基于反射的技术。

    往后看:

    // 缓存早期单例,以便即使在诸如BeanFactoryAware之类的生命周期接口触发时也能够解析循环引用。
    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, new ObjectFactory<Object>() {
            @Override
            public Object getObject() throws BeansException {
                return getEarlyBeanReference(beanName, mbd, bean);
            }
        });
    }
    
    // 初始化bean实例.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            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,调用addSingletonFactory方法:

    	protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
    		Assert.notNull(singletonFactory, "Singleton factory must not be null");
    		synchronized (this.singletonObjects) {
    			if (!this.singletonObjects.containsKey(beanName)) {
    				this.singletonFactories.put(beanName, singletonFactory);
    				this.earlySingletonObjects.remove(beanName);
    				this.registeredSingletons.add(beanName);
    			}
    		}
    	}
    

    把早期对象(早期对象是创建了但还没初始化赋值的对象)放到缓存中,以解决循环依赖。

    继续在doCreateBean往后看:

    // 初始化bean实例.
    Object exposedObject = bean;
    try {
        populateBean(beanName, mbd, instanceWrapper);
        if (exposedObject != null) {
            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);
        }
    }
    

    这里的核心的就是populateBean,对bean的属性进行赋值,后面文章会单独讲。继续看后面那个

    initializeBean,是初始化bean,打开源码看:

    protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged(new PrivilegedAction<Object>() {
                @Override
                public Object run() {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }
    
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
        catch (Throwable ex) {
            throw new BeanCreationException(
                    (mbd != null ? mbd.getResourceDescription() : null),
                    beanName, "Invocation of init method failed", ex);
        }
    
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
        return wrappedBean;
    }
    

    在这里是如果我们的Bean实现了BeanNameAware等aware的接口,在这里就会去来回调用我们的Bean接口实现类的方法。还调用了个invokeInitMethods也是这种开放式接口的用的,如果你的Bean实现了对应的接口,在IOC这就会去调用你实现接口的方法代码。

    最后是调用applyBeanPostProcessorsAfterInitialization,和AOP动态有关的,以后的文章讲。

    回到doCreateBean

    现在只剩最后一段了:

    //如果单例bean已经缓存了,则直接获取            
    if (earlySingletonExposure) {
        Object earlySingletonReference = getSingleton(beanName, false);
        if (earlySingletonReference != null) {
            if (exposedObject == bean) {
                exposedObject = earlySingletonReference;
            }
    //如果不允许在循环引用的情况下使用注入原始bean实例(即使注入的bean最终被包装),并且依赖的bean列表中存在需要创建bean。这时候就说明存在循环依赖
            else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                //根据beanName获取所有依赖的bean的beanName
                String[] dependentBeans = getDependentBeans(beanName);
                Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length);
                for (String dependentBean : dependentBeans) {
                    //删除存在循环依赖的bean    
                    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 " +
                                    "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                }
            }
        }
    }
    
    // Register bean as disposable.
    try {
        //将给定的bean添加到此一次性Bean列表中,这个列表中的bean在Spring关闭的时候会查询里面的bean,并调用实现的销毁方法(包含实现了DisposableBean接口的方法和自定义的destory方法),满足其中一个条件
        // 1.实现了DisposableBean接口
        //2.自定义了destroy方法
        //3.实现了AutoCloseable接口
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }
    

    这里就是把创建好的 bean实例加入 到我们的缓存 池

    总结

    最后总结一下过程

    1571836602417

  • 相关阅读:
    Tyvj 1729 文艺平衡树
    送花
    Tyvj 1728 普通平衡树
    [NOI2004]郁闷的出纳员
    [HNOI2004]宠物收养所
    [HNOI2002]营业额统计
    [NOIP2012] 借教室
    无聊的数列
    忠诚
    XOR的艺术
  • 原文地址:https://www.cnblogs.com/chz-blogs/p/11729051.html
Copyright © 2020-2023  润新知