- 浏览: 288749 次
- 性别:
- 来自: 天津
文章分类
最新评论
-
狼子六:
已经开始用了
Java 枚举7常见种用法 -
相约的旋律:
方法一下面的"public static fianl ...
Java 枚举7常见种用法 -
kiddy2012:
...
[转载]程序员装B指南 -
fancy105:
写得很好,简单明了双全面!
Java 枚举7常见种用法 -
he_wen:
请问一下 G1算法是否在线上使用了?
Garbage First(G1) 日志分析工具
已XmlWebApplicationContext为例,从getBean(String name)方法开始,读一下Spring是怎么通过名字获得bean的。
其他方式类似这个过程。
这个是XmlWebApplicationContext的类继承体系:
首先,getBean(String name)是在BeanFactory接口中定义的,而在AbstractApplicationContext中实现:
public Object getBean(String name) throws BeansException { return getBeanFactory().getBean(name); }
AbstractApplicationContext获得BeanFactory代理,然后用代理获得bean。这个代理的实现的getBean(String name)是在AbstractBeanFactory中实现的:
public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
这里的doGenBean才是真正获得bean的地方,下面逐步分析这个方法:
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); } 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 dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { 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 '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory() { 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())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return (T) bean; }
首先从缓存查找单例:
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); }
如果能从缓存中获得已缓存的单例bean,并且参数args(只能在创建prototype时使用)为空,那么直接返回缓存中的bean,否则继续创建bean:
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); } }
如果能AbstractBeanFactory存在父级BeanFactory,并且当前AbstractBeanFactory不存在bean的定义(BeanDefinition),就把创建bean交给父级Beanfactory。
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); } }
如果父级BeanFactory不存在或者AbstractBeanFactory存在当前bean的定义,那就从BeanDefinition中创建bean。
在用BeanDefinition创建bean过程中首先要递归的解决依赖:
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 dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } }
处理完依赖后,开始创建bean实例。如果bean是单例,则创建这个单例并放入缓存:
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { 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); }
创建bean的实际动作是在createBean方法中,这个方法在AbstractAutowireCapableBeanFactory中实现:
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // Make sure bean class is actually resolved at this point. resolveBeanClass(mbd, beanName); // Prepare method overrides. try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.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, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
createBean方法首先验证要创建bean的Class,然后准备要重写的方法。
接下来,将解析是否创建一个bean的代理而不是正在创建这个bean:
Object bean = resolveBeforeInstantiation(beanName, mbd);
在AbstractAutowireCapableBeanFactory是创建代理具体实现:
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.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
如果代理不为空,就返回代理;否则创建bean:
Object beanInstance = doCreateBean(beanName, mbd, args);
创建过程是在AbstractAutowireCapableBeanFactory中实现的:
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) { 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) { 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 { 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; }
doCreateBean方法主要填充bean的属性,处理依赖关系,处理post-processors,然后生成Constructor,根据测试采用jdk的反射或者CGLIB(默认)生成bean,关于这个过程,有时间再详细说,先欠着吧,这个编辑器太不好用了,真的写写不下去了...
发表评论
-
Java压缩/解压缩二进制文件
2013-02-08 13:56 5738在Java中提供Deflater和Inflater工具类来 ... -
java常用并发工具介绍
2013-02-06 23:22 1625本文主要介绍的工具包括: CountDownLa ... -
Garbage First(G1) 日志分析工具
2012-12-22 22:35 2206G1介绍:http://softbeta.iteye.com/ ... -
Spring源码阅读——Ioc初始化过程
2012-11-20 21:52 1264以web项目启动为例,介绍一下Ioc容器的初始化。 下面这个 ... -
Spring源码阅读——BeanFactory体系结构
2012-10-10 18:10 2238以下是看代的码随笔,想到哪写到哪,没有组织逻辑,见谅见谅。 ... -
生成随机数组
2012-09-11 20:23 10831.要求生成一组n位的数字,0-9...(n个)之间的稠密集合 ... -
O(1)复杂度获得栈中的极值
2012-09-09 23:47 1291设计一个栈,O(1)复杂度实现入栈,出栈,栈中最大值,栈中最小 ... -
ubuntu12.04上编译openjdk7
2012-06-13 15:31 4898获取源码 从openjdk代码仓库获取(比较慢) ... -
jinfo 查看、设置JVM参数
2012-04-25 15:36 5150用法: # jinfo -h Usage: ... -
一些参数,弥补CMS(Concurrent Mark-Sweep)收集器的缺点
2012-03-28 21:11 1679CMS缺点:http://softbeta.iteye ... -
[转载]PrintCompilation 参数解释
2012-03-27 13:59 1547英文不好,所以就不翻译了: b Blocking co ... -
《Head First 设计模式》读书笔记
2012-03-01 11:30 15441.策略模式(Strategy) ... -
解决jrobin图像中文乱码
2012-02-14 23:31 1159目前发现一种方法可以解决,做个标记。 利用字体: RrdG ... -
Java内存管理——垃圾收集概念及特点
2012-02-03 12:37 1060碎碎念,介绍Java内存管 ... -
[转载]hotspot源码(JDK7)
2012-01-19 19:25 1561源码结构图,方便理解: ├─agent ... -
跨平台获取java进程id(Process ID in Java)
2012-01-18 19:20 9158原创地址:http://blog.lichengwu.cn/ ... -
了解CMS(Concurrent Mark-Sweep)垃圾回收器
2011-12-27 20:13 121021.总体介绍: CMS(Concurrent Mark- ... -
fail-fast
2011-12-13 19:34 1045fail-fast:快速失败 一般情况下,在对集合进行迭代( ... -
利用VisualVM监视远程JVM
2011-11-17 20:06 4714VisualVM介绍 VisualVM是集成了多个JDK命令 ... -
[转载]Java 虚拟机指令
2011-10-28 20:18 8040x00 nop 什么都不做 0x01 acon ...
相关推荐
《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...
阅读Spring Core的源码可以帮助我们更深入地理解其工作原理,提高解决问题的能力。通过分析`readme.txt`,我们可以获得关于这个版本的更多细节,例如新特性、已知问题和改进之处。同时,了解XML配置文件的结构和作用...
《Spring源码分析——ApplicationContext》 在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地...
分析Spring源码有助于深入理解其动态代理的工作原理。例如,可以查看`org.springframework.aop.framework.JdkDynamicAopProxy`和`org.springframework.aop.framework.CglibAopProxy`这两个类,它们分别实现了JDK和...
在本篇【框架源码篇 04】中,我们将深入探讨Spring框架的核心概念——Bean定义配置化。Spring是Java领域最广泛使用的依赖注入(Dependency Injection,简称DI)和面向切面编程(Aspect-Oriented Programming,简称...
本压缩包“Spring源码解析”提供了对Spring框架核心组件——IOC(Inversion of Control,控制反转)、AOP(Aspect Oriented Programming,面向切面编程)以及Transaction(事务管理)的源码分析,帮助开发者更全面地...
在源码分析的过程中,读者会深入理解Spring的内部工作机制,例如如何解析配置、如何创建bean实例、如何实现AOP代理等。这将有助于开发者编写更高效、更健壮的代码,也能为参与Spring的扩展或定制打下坚实基础。 总...
### Spring核心源码解读与手动实现SpringMVC #### 一、Spring框架简介 Spring框架是由Rod Johnson在2004年发起的一个开源项目,它是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器。Spring框架的核心特性包括:...
### Spring源码解析知识点 #### 一、Spring IoC 容器详解 ##### 1. BeanFactory —— 最基础的IoC容器 - **概念**:`BeanFactory` 是Spring框架中最基本的IoC容器,它负责管理Bean的生命周期,包括创建、配置和...
在Spring框架中,自动装配(Auto-Wiring)是一种简化依赖注入(Dependency Injection,DI)配置的方式,它允许...通过阅读和理解源码,我们可以更好地掌握Spring自动装配的工作原理,从而更好地利用这一强大的功能。
《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...
在源码分析中,我们首先看到`prepareContext`方法被调用,这是`SpringApplication`类中的一个重要方法,它负责初始化`ApplicationContext`(应用上下文)并为后续的bean加载做准备。 `prepareContext`方法做了以下...
### Spring 源码分析——设计模式篇 #### 一、引言 Spring框架作为Java企业级开发领域中不可或缺的一部分,其内部集成了多种设计模式,不仅有助于提高系统的可维护性和扩展性,还能够帮助开发者更好地理解和应用...
在Spring框架中,自动扫描和管理Bean是一种便捷的方式,它允许开发者无需显式配置每个Bean,而是通过指定包路径来让Spring自动发现和管理Bean。本文将深入探讨这个主题,帮助你更好地理解和应用这一功能。 首先,让...
这两部分源码揭示了Spring如何解析这些配置,创建bean实例,并管理它们之间的依赖关系。 总的来说,这个压缩包中的源码为深入理解Spring的AOP和IOC提供了宝贵的资源。通过对这些源码的学习,开发者不仅可以了解到...
本文将深入探讨这两个技术,并基于提供的资源——"Spring源码深度解析.pdf"和"MyBatis3用户指南中文版.pdf",对它们进行详细的知识点解析。 首先,让我们来了解Spring框架。Spring是一个开源的Java平台,它简化了...
首先,"spring源码UML图"通常包括以下几种类型的UML图: 1. 类图(Class Diagram):类图展示了Spring框架中的类和接口,以及它们之间的关系,如继承、实现、关联和依赖。这有助于我们了解Spring的核心组件,如...
《Spring IOC源码解析(一)——整体介绍》 在深入理解Spring框架的过程中,源码分析是不可或缺的一环。本文将对Spring的IOC(Inversion of Control,控制反转)...希望本文能为你开启Spring源码探索之旅的第一步。
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
在本资源中,我们提供了可以直接导入Eclipse的Spring源码的第五部分,版本为4.3.18。这一版本的Spring包含了众多改进和修复,对于理解Spring的工作原理以及进行自定义开发非常有帮助。 首先,让我们深入了解一下...