上一篇文章中,我们介绍了Spring IoC 的容器初始化过程 - IoC 容器初始化
本篇文章中,我们继续介绍Spring IoC 依赖注入的过程和源码解读。
还是如之前一样,为大家梳理一下步骤流程,以便于大家能在心里有个大概的脉络,更容易读懂源码,更容易抓住重点。
主要内容:
★ 创建singleton 实例
上一章最后一节,容器初始化的倒数第二步, finishBeanFactoryInitialization(beanFactory)
实例化所有单例,调用了 getBean()
方法来做singleton bean 的实例化操作。这就是Spring IoC 依赖注入的入口。
在开始之前,有一点需要提一下。前面我们是从容器初始化之后进来的,但实际操作中,我们有可能是在程序普通运行情况下,用 ApplicationContext.getBean()
去获取容器中bean。不要局限于刚刚的视角中。
现在让我们开始吧。
首先看看 getBean()
源码位置: AbstractBeanFactory#getBean(String name)
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); }
deGetBean()
createBean()
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 反正就是获取到真正beanName // 处理两个情况,1. 将别名转化成真的beanName;2. 把FactoryBean的前缀"&"给去了 final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. // 检测已经注册的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 + "'"); } } // 这个方法还是有点逻辑的 // 如果目前获得的sharedInstance 不是FactoryBean,那bean就赋值成sharedInstance,直接返回 // 如果是FactoryBean就返回FactoryBean创建的实例, // 这个也是FactoryBean的知识点,我在我的另一篇文章也讲过了, bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // 直接翻译:创建过了此 beanName 的 prototype 类型的 bean,那么抛异常 // We're assumably within a circular reference. // 往往是因为陷入了循环引用 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 检查下这个BeanDefinition是否存在 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. // 当前容器没有这个BeanDefinition,去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); } try { // 这个 getMergedLocalBeanDefinition 前面讲过哦 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 先初始化依赖的所有 Bean,这个很好理解。 // 注意,这里的依赖指的是 depends-on 中定义的依赖 String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { // 这里循环依赖概念不要紊乱了 // 这里指的是通过 depends-on 定义造成的循环依赖, // 我们另外一种类成员式的循环引用Spring是支持的 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // 注册依赖关系 // 这么做的原因是Spring在即将进行bean销毁的时候会【首先销毁被依赖的bean】。 // 看SpringBean的初始化和销毁顺序就知道了,依赖关系的保存目的就是这个 // 依赖关系的保存是通过一个ConcurrentHashMap<String, Set>完成的,key是bean的真实名字。 registerDependentBean(dep, beanName); try { // 先去初始化被依赖项 // 递归然后反递归回来 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // Create bean instance. // 如果是 singleton scope 的,创建 singleton 的实例 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { // 创建Bean的详情,等下拉出来单独说 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); } // 如果是 prototype scope 的,创建 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); } // 如果不是 singleton 和 prototype 的话,需要委托给相应的实现类来处理 // 这里非重点,我们的重点是singleton的创建 else { String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + 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; } } // Check if required type matches the type of the actual bean instance. // 最后再检查下类型对不对,不对就抛异常了,对的话就返回 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { 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; }
步骤概览:
三个关注点:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // Instantiate the bean. // 这个BeanWrapper是创建出来持有对象的 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 如果是singleton,先把缓存中的同名bean消除 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); mbd.resolvedTargetType = beanType; // Allow post-processors to modify the merged bean definition. // 涉及接口:MergedBeanDefinitionPostProcessor // 不是关键逻辑,不讲了 synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { try { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex); } mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. // 这里是为了解决循环依赖的,先把初步实例化的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"); } addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { // 时序图中的一步,关键步骤,属性装配,前面的实例只是实例化,没有装配属性 // 和前面的createBeanInstance一样会拉出来讲,继续看下去吧 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { // 还记得 init-method 吗?还有 InitializingBean 接口?还有 BeanPostProcessor 接口? // 这里就是处理 bean 初始化完成后的各种回调 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); } } // 这个逻辑分支我一次性说完吧。 // 如果该beanName对象已经注册单例模式,则从单例中获取,并判断获取到的bean实例(B)与BeanWrapper中的bean实例(A)是同一个实例,如果是,则返回A或者B,如果不是,则递归找出它的依赖bean。 if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); // earlySingletonReference只有在检测到有循环依赖的情况下才会不为空 if (earlySingletonReference != null) { if (exposedObject == bean) { // 两个是同一个引用,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. // 注册DisposableBean; try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
上一步的三个关注点,分开来讲。
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. // 解析出 Class Class<?> beanClass = resolveBeanClass(mbd, beanName); 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()); } // 如果工厂方法不为空,则是用工厂方法初始化 if (mbd.getFactoryMethodName() != null) { // 相关知识点看另一篇文章关于FactoryBean的 return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // 如果不是第一次创建,比如第二次创建 prototype bean。 // 这种情况下,我们可以从第一次创建知道,采用无参构造函数,还是构造函数依赖注入 来完成实例化 // 所以注释说叫shortcut boolean resolved = false; boolean autowireNecessary = false; if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { // 有已经解析过的构造方法 resolved = true; autowireNecessary = mbd.constructorArgumentsResolved; } } } // 如果已经解析过则使用解析好的构造方法不需要再次锁定 if (resolved) { if (autowireNecessary) { // 构造方法自动注入 return autowireConstructor(beanName, mbd, null, null); } else { // 默认构造方法 return instantiateBean(beanName, mbd); } } // Need to determine the constructor... // 判断是否采用有参构造函数 // 构造器自动装配 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // No special handling: simply use no-arg constructor. // 使用无参构造器 return instantiateBean(beanName, mbd); }
入口方法: AbstractAutowireCapableBeanFactory#populateBean
,
它的作用是: 根据autowire类型进行 autowire by name
, by type
或者是直接进行设置
protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) { PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the // state of the bean before properties are set. This can be used, for example, // to support styles of field injection. // 这里看注解是一个扩展点 // InstantiationAwareBeanPostProcessor 的实现类可以在这里对 bean 进行状态修改 // 不是个常用的扩展点,这里不讲了 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; // 如果返回 false,代表不需要进行后续的属性设值,也不需要再经过其他的 BeanPostProcessor 的处理 if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. // 通过类型装配 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE); if (hasInstAwareBpps || needsDepCheck) { PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { // InstantiationAwareBeanPostProcessor.postProcessPropertyValues方法 // 代表能对属性值进行修改的能力 // 其中一个很有用实现类提一下,AutowiredAnnotationBeanPostProcessor // 对采用@Autowired和@Value设值的就是这个BeanPostProcessor干的。 // 不展开讲了,不然要讲不完了 InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } // 这里才是设置bean实例的属性值 applyPropertyValues(beanName, mbd, bw, pvs); }
看这个方法的javadoc 描述
Initialize the given bean instance, applying factory callbacks as well as init methods and bean post processors.
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { @Override public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { // 涉及到的回调接口点进去一目了然,代码都是自解释的 // BeanNameAware、BeanClassLoaderAware或BeanFactoryAware invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessBeforeInitialization 回调 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // init-methods // 或者是实现了InitializingBean接口,会调用afterPropertiesSet() 方法 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessAfterInitialization 回调 wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
大家发现没有,BeanPostProcessor 的两个回调都发生在这边,只不过中间处理了 init-method。这和我原来的认知有点不一样了?因为Spring的源码中代码的命名很多时候是自解释的,很多时候我看英文就知道这些方法的意图,但在这里,为什么BeanPostProcessor的前置处理方法 postProcessBeforeInitialization()
也是在属性设置完成后调用的?
后面查询了去看英文的解释,
BeanPostProcessor is used to interact with newly created bean instances before and/or after their initialization method is invoked by the Spring container . You can use BeanPostProcessor to execute custom logic before and/or after bean’s initialization method is invoked by the Spring container.
BeanPostProcessor的意图就是在初始化方法的前后做定制化操作。仔细想想好像这个命名也没毛病。如果真的是在SpringBean实例化之前调用应该叫 BeforeInstantiation
。源码中的 initialization
指的就是上面的 invokeInitMethods
操作。
以上,就是关于Spring IoC 依赖注入的主要内容。
Spring IoC 容器这里还有一些其他的知识点,有关于SpringIoC 特性的。比如,Spring bean的生命周期、FactoryBean、BeanPostProcessor,都是在使用Spring IoC 容器经常遇到的特性。在了解了IoC容器的整体运行原理以后,你应该能够对这些特性进行一些分析,将你使用这些特性的方法和源码结合起来,融会贯通。
至此,Spring IoC关于依赖注入的源码“大致”解读完毕,还是那句话,上面的源码解析,肯定不会是完备的,只是提取了我认为重要的东西。
如有疏漏,敬请谅解和自己查阅相关资料学习。如果错误,敬请指正!
本文由博客一文多发平台 OpenWrite 发布!