bean的加载(七)创建bean
2016-07-11 15:22
411 查看
常规bean的创建时在doCreateBean中完成的,我们看看这个方法
上面的代码非常的繁琐,每一个步骤都用了大量代码来完成其功能,最复杂也是最难以理解的当属循环依赖的处理,在真正进入doCreateBean前我们有必要了解下循环依赖。关于循环依赖,我也只能说是理解了个大概,有兴趣的话,可以去网上搜索些好的文章加强这方面的理解
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) { //根据指定bean使用对应的策略创建新的实例,如:工厂方法,构造函数自动注入,简单初始化 //实例化bean,将BeanDefinition转化为BeanWrapper. 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. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { //应用MergedBeanDefinitionPostProcessors //bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析。 applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } //是否需要提早曝光:单例&允许循环依赖&当前bean正在创建中,检测循环依赖 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"); } //为避免后期循环依赖,可以在bean初始化完成前将创建实例的ObjectFactory加入工厂 //依赖处理:在Spring中会有循环依赖的情况,例如,当A中含有B的属性,而B中又含有A的属性时就会 //构成一个循环依赖,此时如果A和B都是单例,那么在Spring中的处理方式就是当创建B的时候,涉及 //自动注入A的步骤时,并不是直接去再次创建A,而是通过放入缓存中的ObjectFactory来创建实例, //这样就解决了循环依赖的问题。 addSingletonFactory(beanName, new ObjectFactory<Object>() { public Object getObject() throws BeansException { //对bean再一次依赖引用,主要应用SmartInstantiationAware BeanPostProcessor, //其中我们熟知的AOP就是在这里将advice动态植入bean中,若没有则直接返回bean,不做任何处理 return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { //对bean进行填充,将各个属性值注入,其中,可能存在依赖于其他bean的属性,则会递归初始依赖bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //调用初始化方法,比如init-method. 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) { //由于earlySingletonObjects是用于存储在创建bean早期对创建的原始bean的一个引用, //所以返回的earlySingletonReference只有在检测到检测到循环依赖的情况下才会不为空 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //如果exposedObject没有在初始化方法中被改变,也就是没有被 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) { //检测依赖 //之前说过,在Spring中解决循环依赖只对单例有效,而对于prototype的bean,Spring没有好的解决 //办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的bean是否已经出现了依赖循环,并 //判断是否需要抛出异常 if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } /* * 因为bean创建后其所依赖的bean一定是已经创建的。 * actualDependentBeans不为空则表示当前bean创建后其依赖的bean却没有全部 * 创建完,也就是存在循环依赖。 */ 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 { //根据scope注册bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
上面的代码非常的繁琐,每一个步骤都用了大量代码来完成其功能,最复杂也是最难以理解的当属循环依赖的处理,在真正进入doCreateBean前我们有必要了解下循环依赖。关于循环依赖,我也只能说是理解了个大概,有兴趣的话,可以去网上搜索些好的文章加强这方面的理解
相关文章推荐
- iOS 开发笔记
- C语言入门(三)菜单设置
- java自定义标签 权限
- 错题集锦(二) -- Java专项
- Hdu3714-Error Curves(三分)
- Linux共享内存的内核实现
- JVM概念之Java对象的大小与引用类型
- bzoj 2440: [中山市选2011]完全平方数
- Lowest Common Ancestor of a Binary Search Tree
- MySql数据库查询结果用表格输出PHP代码示例
- SQL的基本操作
- iOS 富文本
- android 打包成jar包(转)
- 关于C# Dockpanel的一些入门的基本操作
- 怎么设置 运行bat 文件不弹出CMD窗口
- struts2 标签<s:submit />怎么加css样式(
- java web项目开发环境
- nginx优化
- python脚本――自动推送txt,EXCEL等文件模板
- SSH面试题