Spring源码阅读-BeanFactory-对象创建过程
2016-12-27 00:00
344 查看
摘要: 学习spring都听过ioc这个词,getBean方法里面就是IOC工作的地方。
还是以XmlBeanFactory跟踪代码看一下getBean流程,最终进入到AbstractBeanFactory的doGetBean方法:
先把传人的name转变成真实的对象名称beanName: 传人的name称可能是别名或者工厂名(工厂名前缀为&)
用beanName到缓存里获取单例对象,如果为空则走下面流程,这步是针对单例对象的,这里有三层缓存(为了解决循环依赖,后面单独叙述,这里主要看主流程,否则会绕进去)。
原型依赖检查,循环依赖只有在单例情况下可用,原型情况下向上抛异常
如果BeanDefinitionMap中没有对应的bean,则到parentBeanFactory去寻找
如果上面都没获取到对象,则用beanName获取BeanDefinition转成RootBeanDefinition对象,后面不同类型的scope都是根据RootBeanDefinition创建的。
先创建BeanDefinition的dependsON对象(bean标签的depends-on属性,depends-on标签不能循环依赖)
根据bean的scope走不同的创建流程,针对不同scope做了不同的控制,比如:singleton模式通过getSingleton方法,这个里面创建对象时会先校验缓存是否已经存在该对象,prototype模式直接创建对象,其他类型的则可以通过自定义Scope来实现逻辑控制,设想一下如果把对象放到第三方缓存中则可在这边自定义一个Scope。最终bean的构造委托给了createBean,createBean方法比较复杂,下面单独看。
上面获取到的对象最终都需要再次校验一下,因为获取的对象也可能是个工厂,这里校验的方法就是getObjectForBeanInstance
用TypeConverter转成最终需要的类型。
时序图如下:
这里分为三个核心过程:
先创建bean,
然后把填充bean的属性,这个里面就是解析了依赖对象,
最后调用initializeBean初始化bean.
这三部分里面都比较复杂,后面有时间再看,看一下createBean的时序图:
1 getBean
上一节只是加载配置,并把文件内容映射到BeanDefinition中,真正的创建对象跟依赖注入是在getBean中处理的,这里实际上就是根据BeanDefinition用反射创建对象及其依赖对象,只不过spring里面处理的比较复杂,这里面的每一步都有很多逻辑处理,并且在这前后做了很多的异常的判断校验。还是以XmlBeanFactory跟踪代码看一下getBean流程,最终进入到AbstractBeanFactory的doGetBean方法:
protected <T> T doGetBean(final String name, final Class<T> 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); } } 3ff0 //7 不同scope情况下创建对象 // Singleton情况 // Create bean instance. if (mbd.isSingleton()) { //getSingleton有单例的控制, 防止前面已经创建过该对象,如果没创建过该对象最终也是调用createBean 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; } } }); //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<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; } } //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; }
先把传人的name转变成真实的对象名称beanName: 传人的name称可能是别名或者工厂名(工厂名前缀为&)
用beanName到缓存里获取单例对象,如果为空则走下面流程,这步是针对单例对象的,这里有三层缓存(为了解决循环依赖,后面单独叙述,这里主要看主流程,否则会绕进去)。
原型依赖检查,循环依赖只有在单例情况下可用,原型情况下向上抛异常
如果BeanDefinitionMap中没有对应的bean,则到parentBeanFactory去寻找
如果上面都没获取到对象,则用beanName获取BeanDefinition转成RootBeanDefinition对象,后面不同类型的scope都是根据RootBeanDefinition创建的。
先创建BeanDefinition的dependsON对象(bean标签的depends-on属性,depends-on标签不能循环依赖)
根据bean的scope走不同的创建流程,针对不同scope做了不同的控制,比如:singleton模式通过getSingleton方法,这个里面创建对象时会先校验缓存是否已经存在该对象,prototype模式直接创建对象,其他类型的则可以通过自定义Scope来实现逻辑控制,设想一下如果把对象放到第三方缓存中则可在这边自定义一个Scope。最终bean的构造委托给了createBean,createBean方法比较复杂,下面单独看。
上面获取到的对象最终都需要再次校验一下,因为获取的对象也可能是个工厂,这里校验的方法就是getObjectForBeanInstance
用TypeConverter转成最终需要的类型。
时序图如下:
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; }
这里分为三个核心过程:
先创建bean,
然后把填充bean的属性,这个里面就是解析了依赖对象,
最后调用initializeBean初始化bean.
这三部分里面都比较复杂,后面有时间再看,看一下createBean的时序图:
相关文章推荐
- 2、Spring的LocalSessionFactoryBean创建过程源码分析
- Spring Aop(十三)——ProxyFactoryBean创建代理对象
- 自己写BeanFactory,实现读取配置文件,并根据发射创建对象。
- Spring 源码阅读 BeanFactory(三) 对象的初始化 singleton 草稿
- XmlBeanFactory创建容器过程
- Spring源码阅读——Bean的加载和获取过程
- 菜鸟瞎扯――对象的创建过程
- (转载)JAVA中对象创建和初始化过程
- C++类对象创建过程揭密
- C++类对象创建过程揭密
- JAVA中对象创建和初始化过程
- Java:对象创建和初始化过程
- Java 小例子:根据 Map 对象的内容创建 JavaBean
- 如何使用 Visual Studio .NET 工具创建数据库对象和 Transact-SQL 存储过程。
- Com对象创建过程
- 用ProxyFactoryBean创建AOP代理
- C++类对象创建过程揭密
- Spring中如何获取和重置一个BeanFactory对象?或者说,如何动态修改Hibernate Configuration?
- Factory 定义一个接口,客户可以使用这个接口创建一个对象.同时,我们还可以控制对那个类进行实例化
- Java:对象创建和初始化过程