基于Spring注解的上下文初始化过程源码解析(三)
上一篇跟完了 refresh 方法中第一个重要的方法 invokeBeanFactoryPostProcessors,
这篇继续分析 refresh 方法中第二个比较重要的 finishBeanFactoryInitialization 方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { /** * 初始化此上下文的转换服务 */ if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } /** * 如果之前没有注册 bean 后置处理器(例如 PropertyPlaceholderConfigurer) * 则注册默认的嵌入值解析器:此时主要用于注释属性值的解析 */ if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 获取 LoadTimeWeaverAware 的 BeanName 集合 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { // 初始化 LoadTimeWeaverAware 以允许尽早注册其变换器 getBean(weaverAwareName); } // 停止使用临时 ClassLoader 进行类型匹配 beanFactory.setTempClassLoader(null); // 允许缓存所有 BeanDefinition 元数据,不期望进一步更改 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. // 实例化所有不是懒加载的单例对象 beanFactory.preInstantiateSingletons(); }
实例化所有非懒加载的单例对象方法中包含了 getBean 方法,先看 preInstantiateSingletons 方法
public void preInstantiateSingletons() throws BeansException { // 所有已注册的 BeanName 集合 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // 触发所有非延迟加载单例 Bean 的初始化,主要步骤为调用 getBean()方法 for (String beanName : beanNames) { // 合并父 BeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 不是抽象类、是单例且不是懒加载的 Bean if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 判断该 Bean 是否是一个 FactoryBean if (isFactoryBean(beanName)) { /** * 如果是 FactoryBean 则需要加上&才能实例化该 Bean * 否则实例化的是该 FactoryBean 生产的对象 */ Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); // 再次确认是 FactoryBean 的子类 if (bean instanceof FactoryBean) { // 强转为父类 final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; /** * SecurityManager 不为空并且是 SmartFactoryBean 的子类 * * SmartFactoryBean 的子类有 EagerInitFactory 和 NonPrivilegedFactoryBean */ if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { // isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { // 是 SmartFactoryBean 的子类并且是迫切需要被实例化的 isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } // 如果是迫切需要被实例化的类,则实例化 if (isEagerInit) { getBean(beanName); } } } else { // 实例化 getBean(beanName); } } } // 触发所有适用 bean 的后初始化回调 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); /** * 是 SmartInitializingSingleton 的子类 * * EventListenerMethodProcessor 是 SmartInitializingSingleton 的子类 */ if (singletonInstance instanceof SmartInitializingSingleton) { // 强转为 SmartInitializingSingleton final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { // 回调 afterSingletonsInstantiated 方法 smartSingleton.afterSingletonsInstantiated(); } } } }
getBean 方法是一个空壳方法,内部调用了 doGetBean 方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { /** * 通过 name 获取 BeanName。这里不使用 name 直接作为 BeanName 有两个原因: * * 1.name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 对象本身的实例, * 而非 FactoryBean 实现类所创建的 Bean 对象实例。 * 在 BeanFactory 中,FactoryBean 的实现类和其他的 Bean 存储方式是一致的, * 即<BeanName, BeanInstance>,BeanName中是没有 & 这个字符的, * 所以需要将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 创建的实例 * 2.该 Bean 对象可能存在别名的问题 */ // 解析 BeanName 为规范名称 final String beanName = transformedBeanName(name); Object bean; /** * 解决循环依赖问题【通过两次重载的 getSingleton() 方法和一次后置处理器方法的调用来解决循环依赖】 */ // 第一次调用 getSingleton() 方法,检查单个缓存以手动注册单例。 // 获取在给定名称下注册的(原始)单例对象。 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (logger.isTraceEnabled()) { if (isSingletonCurrentlyInCreation(beanName)) { logger.trace("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference"); } else { logger.trace("Returning cached instance of singleton bean '" + beanName + "'"); } } // 获取给定 bean 实例的对象,如果是 FactoryBean,则为 bean 实例本身或其创建的对象。 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 已经创建过该实例对象 else { // 如果已经创建了这个 bean 实例,则会失败:我们可以在循环引用中完成。 // prototype 对象在每次 get 的时候创建,单例则不需要创建 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // 检查此工厂中是否存在 BeanDefinition BeanFactory parentBeanFactory = getParentBeanFactory(); // 父工厂存在且不包含解析后的 beanName if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { // 转换调用 doGetBean 方法 return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // 使用显式 args 委托父级 return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // 没有参数,委托标准的 getBean 方法 return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // 校验是否是抽象的 checkMergedBeanDefinition(mbd, beanName, args); // 初始化当前 Bean 依赖的 Bean【被 @DependsOn 注解指明需要依赖的 Bean】 // Guarantee initialization of beans that the current bean depends on. String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { // 校验是否是依赖项 if (isDependent(beanName, dep)) { // 抛出循环依赖异常 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'"); } // 为给定 bean 注册依赖 bean registerDependentBean(dep, beanName); try { // 获取给定的 bean 实例 getBean(dep); } catch (NoSuchBeanDefinitionException ex) { // 抛出依赖项缺失异常 throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex); } } } // 创建 Bean 实例 if (mbd.isSingleton()) { // 第二次调用,解决循环依赖问题 sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 原型则创建新的实例 Object prototypeInstance; 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 name '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, () -> { 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 && !requiredType.isInstance(bean)) { try { T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType); if (convertedBean == null) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return convertedBean; } catch (TypeMismatchException ex) { if (logger.isTraceEnabled()) { logger.trace("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex); } throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } } return (T) bean; }
FactoryBean 是一种特殊的 Bean,能产生新的 Bean,获取的时候需要加’&’字符,否则获取的是其产生的 Bean。
Spring在这一步完成了所有非延迟加载的单例对象的初始化,至此 Spring 的 BeanFactory 就初始化完成了,分析的比较浅,也没有进行总结,后面会继续补充和完善,并辅以图表和示例代码。
相关文章