spring源码 — 二、从容器中获取Bean
2016-10-22 21:17
405 查看
getBean
上一节中说明了容器的初始化,也就是把Bean的定义GenericBeanDefinition放到了容器中,但是并没有初始化这些Bean。那么Bean什么时候会初始化呢?在程序第一个主动在getBean的时候,
在完成容器初始化的时候会初始化lazy-init配置为false或者未配置的Bean(默认是false)
getBean初始化的时候主要做了哪些事?
得到一个指定类的对象,先从缓存中get,如果没有则new 一个对象
如果是new的对象,则需要装配——初始化对象的一些属性,包括简单属性,如:int,long等类型,包括引用属性,这个时候就会引起依赖注入
整个获取过程如下:
整个图片较大,看起来不清晰,可以右键-在新标签页中打开,就可以放大看了
注意:以上的时序图是从spring容器初始化的时候会初始化配置为lazy-init=false的Bean,不过过程和我们通过getBean获取Bean的过程一样
从上面的调用过程获取Bean是从AbstractAutowirecapableBeanFactory的doGetBean方法开始的
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 因为获取的可能是以"&"开头的FactoryBean,所以要进行转化(关于BeanFactory和FactoryBean后面会进行区分) final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 先从缓存中获取,因为在容器初始化的时候或者其他地方调用过getBean,已经完成了初始化 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. // spring的容器机制:先检查本容器,如果没有再查找父容器 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的BeanDefinition用上了 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) { // 触发了依赖注入,循环递归初始化依赖的bean for (String dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. // 创建bean,根据不同的scope进行创建,关于spring的scope介绍,文末有参考链接 if (mbd.isSingleton()) { // 初始化Bean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { try { // 在匿名类中调用AbstractAutowireCapableBeanFactory的createBean 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 '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { 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); } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { 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; }
上面createBean交给了doCreateBean来创建bean(上面还有一个重要的方法getObjectForBeanInstance,在后面分析)
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 使用CglibSubclassingInstantiationStrategy调用BeanUtils的instantiateClass实例化类,在instanceClass方法中利用反射通过构造方法实例化bean instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // Allow post-processors to modify the merged bean definition. // bean初始化前调用post-processors,我们可以在bean实例化之前定制一些操作 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); 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() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { // 在这个方法里面初始化对象,设置xml配置的各种属性 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, "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 { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
上面这个方法里面完成了bean的实例化和初始化,已经具备一个普通bean的功能了,但是spring提供了一种增强的bean——FactoryBean,具备factory能力的Bean,这个能力主要在getObjectForBeanInstance得到
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // Don't let calling code try to dereference the factory if the bean isn't a factory. if (BeanFactoryUtils.isFactoryDereference(name) && !(beanInstance instanceof FactoryBean)) { throw new BeanIsNotAFactoryException(transformedBeanName(name), beanInstance.getClass()); } // Now we have the bean instance, which may be a normal bean or a FactoryBean. // If it's a FactoryBean, we use it to create a bean instance, unless the // caller actually wants a reference to the factory. // 在这里判断是否时=是FactoryBean,如果不是则直接返回 if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // Return bean instance from factory. FactoryBean<?> factory = (FactoryBean<?>) beanInstance; // Caches object obtained from FactoryBean if it is a singleton. if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); // 在这里面获得最终的FactoryBean object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; }
关于BeanFactory和FactoryBean的区别:
BeanFactory:容器的基本接口,是一个工厂,用来生产Bean
FactoryBean:是一个特殊的Bean,可以当作工厂使用的Bean
总结
到这里就完成了bean的初始化,先通过反射实例化bean,然后通过配置的属性初始化bean,然后然会给用户。spring中的scope
相关文章推荐
- spring源码 — 二、从容器中获取Bean
- Spring IOC 容器源码分析 - 获取单例 bean
- 获取Spring 容器中bean的方法
- 通过ApplicationContextAware获取spring容器中的bean
- 使用监听获取spring容器的bean
- spring3 bean容器相关源码学习----ApplicationContext接口
- 通过ApplicationContextAware获取spring容器中的bean
- Spring-Bean的销毁使用destroy-method()方法无效解决方案(容器!附源码)
- 7.4.5:让Bean获取Spring容器
- 7.4.5: 使用Spring容器---让Bean获取Spring容器
- 获取Spring容器中Bean实例的工具类(Java泛型方法实现)
- 在Bean中获取Spring容器中的各种组件
- Struts 2在Action中获取Spring容器中所有Bean实例名称的方法
- spring源码学习之路---IOC容器初始化要义之bean定义载入
- java类获取spring容器的bean
- Spring动态获取IoC容器中管理的Bean
- 获取Spring 容器中bean的方法
- spring_spring容器以外类获取spring容器内部Bean
- Spring源码学习IOC(3):IoC容器载入Bean定义资源文件
- 获取Spring的Bean持有容器对象的方法