本篇我们讲上一篇中没有讲到的createBean方法,是在上一篇的代码块10中被调用这个方法,这个方法是位于AbstractAutowireCapableBeanFactory中:
代码块1 @Override protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // 1.这个是确保mbd的beanClass属性是有值的 resolveBeanClass(mbd, beanName); try { // 2. 验证以及准备mbd的方法覆盖属性 mbd.prepareMethodOverrides(); }catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 3. 这里主要是来针对代理的处理,如果是有代理之类需要替代真正bean的,就在这里返回结果了 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); } // 4. 创建bean实例(这个才是真正创建bean的方法) Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
1.1
代码块2 protected Class<?> resolveBeanClass(final RootBeanDefinition mbd, String beanName, final Class<?>... typesToMatch) throws CannotLoadBeanClassException { try { // 如果mbd已经有beanClass,则直接结束方法 // 返回值是类的全类名,这里一般都有的 if (mbd.hasBeanClass()) { return mbd.getBeanClass(); } // 这块还是和之前一样,if是特权执行,else是普通方式执行 // 都是获取bean的全类名 if (System.getSecurityManager() != null) { return AccessController.doPrivileged(new PrivilegedExceptionAction<Class<?>>() { @Override public Class<?> run() throws Exception { // 1. 真正解析bean的class return doResolveBeanClass(mbd, typesToMatch); } }, getAccessControlContext()); } else { return doResolveBeanClass(mbd, typesToMatch); } } catch (PrivilegedActionException pae) { ClassNotFoundException ex = (ClassNotFoundException) pae.getException(); throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (ClassNotFoundException ex) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex); } catch (LinkageError err) { throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err); } }
我们来看代码块2中的1处
代码块3 private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) throws ClassNotFoundException { // 此时typesToMatch是个空数组,因此if跳过去 if (!ObjectUtils.isEmpty(typesToMatch)) { ClassLoader tempClassLoader = getTempClassLoader(); if (tempClassLoader != null) { if (tempClassLoader instanceof DecoratingClassLoader) { DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader; for (Class<?> typeToMatch : typesToMatch) { dcl.excludeClass(typeToMatch.getName()); } } String className = mbd.getBeanClassName(); return (className != null ? ClassUtils.forName(className, tempClassLoader) : null); } } // 返回bean的全类名,返回值为mbd中的beanClass属性,也就是bean的类型 // 注意是全类名哈 return mbd.resolveBeanClass(getBeanClassLoader()); }
1.2
这里的prepareMethodOverrides是在AbstractBeanDefinition中:
代码块4 public void prepareMethodOverrides() throws BeanDefinitionValidationException { MethodOverrides methodOverrides = getMethodOverrides(); // methodOverrides存在并且不是空,则准备方法覆盖 // 都是look-up(注解为@lookup)的方法和replace-method if (!methodOverrides.isEmpty()) { for (MethodOverride mo : methodOverrides.getOverrides()) { prepareMethodOverride(mo); } } }
上面的代码是你的xml必须使用look-upmethod以及replace的时候才会执行到,我们来看上面最后调用的这个prepareMethodOverride方法:
代码块5 protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { // 计算重载的方法的数量 int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); // 0就直接抛出异常 if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); // 1的话设置这个属性为true,这个属性的作用是避免掉重载的检查 // 可以在运行的时候提高性能 } else if (count == 1) { // Mark override as not overloaded, to avoid the overhead of arg type checking. mo.setOverloaded(false); } }
1.3
这里主要是生成各种代理的,比如说当你使用Dubbo中的@Reference注解注入一个服务对象的时候,这时候就是走的这里,我们来看看它的代码:
代码块6 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; // 如果需要提前执行InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation方法 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // mbd有正确的class属性 && mbd不是合成的 && 存在InstantiationAwareBeanPostProcessor(这是个特殊的BeanPostProcessor) if (mbd.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { // 1.执行postProcessBeforeInstantiation方法 bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); // 如果在这里返回了result,则执行所有的BeanPostProcessor的后置处理方法 // 执行完了就代表一个完整的bean已经创建好 if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
我们可以看出来,这块主要是来执行InstantiationAwareBeanPostProcessor的,为什么要在代码块1.3中这里调用呢?因为要给代理类一个机会替换掉原来的对象的,因为下一步就要在代码块1.4处都要调用doCreateBean创建真正的bean实例了。然后我们来看看代码块6中的1处,其实这里便是对应着执行InstantiationAwareBeanPostProcessor
代码块7 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { // 遍历BeanPostProcessor for (BeanPostProcessor bp : getBeanPostProcessors()) { // 如果BeanPostProcessor 是个 InstantiationAwareBeanPostProcessor if (bp instanceof InstantiationAwareBeanPostProcessor) { // 强制转型 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
1.4
终于到这个doCreateBean方法了,这里才是真正创建bean的方法,也是包含逻辑最多的方法,我们不虚它,就是干,但是干之前,因为这个方法太过于复杂的原因,我先给你列个提纲,从宏观上告诉你这个方法都做了什么事情,再给你看源码,这样你就不至于很懵逼
这个doCreateBean方法,做了这些事情:1. 从工厂方法或者构造方法中二选一创建对象(取决于你的配置,这里包含的逻辑也最多,涉及到了构造方法的选择) 2. 接着是循环依赖的处理,主要是通过提前曝光的方式来处理 3. 进行属性的填充以及初始化操作,初始化中包含着bean的前置以及后置处理。
接着,我们来看看具体的代码:
代码块8 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // BeanWrapper是bean的包装类 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 从正在创建的factoryBean的缓存中移除(准确说其实是去拿,同时移除) instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 1. 如果到这里是null,则去创建一个包含着bean实例的instanceWrapper instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); // 使用MergedBeanDefinitionPostProcessor修改RootBeanDefinition // 主要是处理@Autowired 、 @inject 、@value 标着的方法和属性 // 从这里往后,spring 才知道是哪个方法或者是属性有这个注解 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // earlySingletonExposure是判断是否要提前曝光这个半成品的实例的,注意哈:现在的bean只是个半成品 // 因为还没有进行属性填充,以及执行初始化方法等操作 // mbd是单例 && 允许循环引用(默认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"); } // 提前曝光这个beanName对应的ObjectFactory,用来解决循环引用 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { // 2.使用SmartInstantiationAwareBeanPostProcessor返回早期bean的半成品时的引用 // 如果没有SmartInstantiationAwareBeanPostProcessor,则直接返回bean // 这里返回的最终是bean本身 return getEarlyBeanReference(beanName, mbd, bean); } }); } // 初始化 Object exposedObject = bean; try { // 3. 对bean进行属性填充 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 4. 初始化操作 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); } } // 如果需要提前曝光半成品bean if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { // 由于经过init之后的操作,earlySingletonReference和exposedObject可能不是一个实例, // 这里需要让他们指向一个实例, exposedObject = earlySingletonReference; // 不允许在循环依赖情况下注入原始bean && 当前bean被其他bean依赖 }else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { // 拿到当前bean依赖所有bean的数组 String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { // 移除这些bean,因为这些bean依赖的bean是被增强过的bean if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { // 移除失败的添加到actualDependentBeans 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."); } } } } try { // 注册用于销毁的bean, registerDisposableBeanIfNecessary(beanName, bean, mbd); }catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
这个doCreateBean方法,是整个spring 创建bean流程核心中的核心,当然难度也比较高,这部分代码是需要反复读的,最好你看我文章的同时还能去源码中跟一跟。这里面难度最大的方法也是这个第1处的代码(本篇也只讲这个方法,剩下的下一篇讲),这个代码创建了一个”不完整”的bean,为什么是不完整的呢?因为此时创建出来的bean还没有被进行属性填充,也就是被@Autowired以及@Resource标记的属性都还没有被注入。我们一起来看看这个方法:
代码块9 // 使用不同的策略创建bean 实例 protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // 拿到mbd的全类名,上一篇已经说过resolveBeanClass方法 Class<?> beanClass = resolveBeanClass(mbd, beanName); // beanClass不为null && beanClass是不是公共类(public修饰) && beanClass不允许访问非public的构造方法 // 上述条件都满足就抛异常,因为都满足的话就没有构造方法可以调用了 if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } // 如果存在factory-method,则使用factory-method创建BeanWrapper if (mbd.getFactoryMethodName() != null) { // 1. 根据工厂方法来创建包含着bean实例的BeanWrapper实例 return instantiateUsingFactoryMethod(beanName, mbd, args); } // resolved表示构造方法或者工厂方法已经被解析过,autowireNecessary代表是否要解析构造方法参数 boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { // resolvedConstructorOrFactoryMethod不为空,说明已经解析过,resolved标为true if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; // constructorArgumentsResolved如果是true,那autowireNecessary肯定是true // constructorArgumentsResolved源码注释的意思是构造方法参数是否已经被解析过 autowireNecessary = mbd.constructorArgumentsResolved; } } } // 如果已经解析过 if (resolved) { // 并且是需要解析构造方法参数 if (autowireNecessary) { // 2. 能走到这里的前提是你的bean是个可以被多次解析的bean,也就是prototype, // 事实上也只有prototype并且是个构造方法注入的resolved和autowireNecessary才都会是true // 原因是singleton的会被缓存,再次getbean()的话根本都走不到这里来 return autowireConstructor(beanName, mbd, null, null); }else { // 3.使用无参数的构造方法注入 return instantiateBean(beanName, mbd); } } // 去拿候选的构造方法, Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); // 候选构造方法不是空 || 构造方法注入的方式 || mdb中有构造方法的参数值 || 参数不为空 // 详细解释下这四个条件:(1)候选构造方法不是空是当注解情况下有@Autowired或@inject标着的构造器或者是你的类只有一个有参数构造 // 或者你自己有实现了SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法 // (2)是构造方法注入,(3)或者所需要的构造方法是有参的构造方法(因为某些时候我们的类只定义了一个有参构造),在或者就是 // (4)传过来的参数不是null if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 执行构造方法注入(和2处是一个方法,只是参数不一样) return autowireConstructor(beanName, mbd, ctors, args); } // 使用无参数的构造方法注入 return instantiateBean(beanName, mbd); }