博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Spring源码阅读-BeanFactory-对象创建过程
阅读量:6167 次
发布时间:2019-06-21

本文共 7859 字,大约阅读时间需要 26 分钟。

hot3.png

1 getBean

上一节只是加载配置,并把文件内容映射到BeanDefinition中,真正的创建对象跟依赖注入是在getBean中处理的,这里实际上就是根据BeanDefinition用反射创建对象及其依赖对象,只不过spring里面处理的比较复杂,这里面的每一步都有很多逻辑处理,并且在这前后做了很多的异常的判断校验。

还是以XmlBeanFactory跟踪代码看一下getBean流程,最终进入到AbstractBeanFactory的doGetBean方法:

protected 
T doGetBean(final String name, final Class
requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { //1 去掉工厂bean的前缀& 并找到alias对应的名称 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. //2 先从缓存中获取 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工厂,则创建对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: We're assumably within a circular reference. //3 在原形情况下创建循环依赖就会报错 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //4 Check if bean definition exists in this factory. BeanFactory parentBeanFactory = getParentBeanFactory(); //如果存在父bean工厂并且没有配置该bean,则从父bean工厂创建 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. String nameToLookup = originalBeanName(name); //递归调用getBean 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 { //5 转换BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); //6 depends-on标签 // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dependsOnBean : dependsOn) { if (isDependent(beanName, dependsOnBean)) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dependsOnBean + "'"); } registerDependentBean(dependsOnBean, beanName); //递归调用 getBean(dependsOnBean); } } //7 不同scope情况下创建对象 // Singleton情况 // Create bean instance. if (mbd.isSingleton()) { //getSingleton有单例的控制, 防止前面已经创建过该对象,如果没创建过该对象最终也是调用createBean sharedInstance = getSingleton(beanName, new ObjectFactory
() { @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; } } }); //8 获取最终的对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //prototype情况 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() { @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; } } //9 类型转换 // 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;}
  1. 先把传人的name转变成真实的对象名称beanName: 传人的name称可能是别名或者工厂名(工厂名前缀为&)
  2. 用beanName到缓存里获取单例对象,如果为空则走下面流程,这步是针对单例对象的,这里有三层缓存(为了解决循环依赖,后面单独叙述,这里主要看主流程,否则会绕进去)。
  3. 原型依赖检查,循环依赖只有在单例情况下可用,原型情况下向上抛异常
  4. 如果BeanDefinitionMap中没有对应的bean,则到parentBeanFactory去寻找
  5. 如果上面都没获取到对象,则用beanName获取BeanDefinition转成RootBeanDefinition对象,后面不同类型的scope都是根据RootBeanDefinition创建的。
  6. 先创建BeanDefinition的dependsON对象(bean标签的depends-on属性,depends-on标签不能循环依赖)
  7. 根据bean的scope走不同的创建流程,针对不同scope做了不同的控制,比如:singleton模式通过getSingleton方法,这个里面创建对象时会先校验缓存是否已经存在该对象,prototype模式直接创建对象,其他类型的则可以通过自定义Scope来实现逻辑控制,设想一下如果把对象放到第三方缓存中则可在这边自定义一个Scope。最终bean的构造委托给了createBean,createBean方法比较复杂,下面单独看。
  8. 上面获取到的对象最终都需要再次校验一下,因为获取的对象也可能是个工厂,这里校验的方法就是getObjectForBeanInstance
  9. 用TypeConverter转成最终需要的类型。

时序图如下:

201353_9YIU_1445156.png

2 createBean

上面第7步,创建对象委托给了createBean,createBean中做一下初始化确认就把创建对象委托给了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) {		//1. 创建对象		instanceWrapper = createBeanInstance(beanName, mbd, args);	}	final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);	Class
beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); //...省略 // Initialize the bean instance. Object exposedObject = bean; try { //2. 填充对象 这个里面解析了依赖的bean populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //3. 初始化方法 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); } } //...省略 // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject;}

这里分为三个核心过程:

  1. 先创建bean,
  2. 然后把填充bean的属性,这个里面就是解析了依赖对象,
  3. 最后调用initializeBean初始化bean.

这三部分里面都比较复杂,后面有时间再看,看一下createBean的时序图:

202114_VySI_1445156.png

转载于:https://my.oschina.net/chengxiaoyuan/blog/813172

你可能感兴趣的文章
Eclipse工具进行Spring开发时,Spring配置文件智能提示需要安装STS插件
查看>>
NSURLCache内存缓存
查看>>
jquery click嵌套 事件重复注册 多次执行的问题
查看>>
Dev GridControl导出
查看>>
开始翻译Windows Phone 8 Development for Absolute Beginners教程
查看>>
Python tablib模块
查看>>
站立会议02
查看>>
Windows和Linux如何使用Java代码实现关闭进程
查看>>
0428继承性 const static
查看>>
第一课:从一个简单的平方根运算学习平方根---【重温数学】
查看>>
NET反射系统
查看>>
Oracle12C本地用户的创建和登录
查看>>
使用JS制作一个鼠标可拖的DIV(一)——鼠标拖动
查看>>
《Javascript高级程序设计》阅读记录(三):第五章 上
查看>>
root方式细节剖析
查看>>
ios开发之--MJRefresh的简单使用
查看>>
Ionic3与Angular4新特性
查看>>
论文查重福利
查看>>
关注云端搜索技术:elasticsearch,nutch,hadoop,nosql,mongodb,hbase,cassandra 及Hadoop优化...
查看>>
poj2629
查看>>