1 getBean
上一节只是加载配置,并把文件内容映射到BeanDefinition中,真正的创建对象跟依赖注入是在getBean中处理的,这里实际上就是根据BeanDefinition用反射创建对象及其依赖对象,只不过spring里面处理的比较复杂,这里面的每一步都有很多逻辑处理,并且在这前后做了很多的异常的判断校验。
还是以XmlBeanFactory跟踪代码看一下getBean流程,最终进入到AbstractBeanFactory的doGetBean方法:
protectedT 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
- 先把传人的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的时序图: