1、源码解析
1.1、整体逻辑剖析
finishBeanFactoryInitialization(beanFactory);初始化非懒加载的单实例,完成IOC容器的初始化操作。1 // 完成IOC容器的初始化操作 2 protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { 3 // 为上下文初始化类型转换器 4 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && 5 beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { 6 beanFactory.setConversionService( 7 beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); 8 } 9 // 如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器,主要用于注解属性值的解析 10 if (!beanFactory.hasEmbeddedValueResolver()) { 11 beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); 12 } 13 // 尽早初始化loadTimeWeaverAware bean,以便尽早注册它们的转换器,用于AOP 14 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); 15 for (String weaverAwareName : weaverAwareNames) { 16 getBean(weaverAwareName); 17 } 18 // 禁止使用临时类加载器进行类型匹配 19 beanFactory.setTempClassLoader(null); 20 // 冻结所有的bean定义,说明注册的bean定义将不被修改或任何进一步的处理(在Bean实例化阶段) 21 beanFactory.freezeConfiguration(); 22 // 实例化剩下的单例对象 23 beanFactory.preInstantiateSingletons(); 24 }
完成IOC容器的核心方法在beanFactory.preInstantiateSingletons();这一步骤中。preInstantiateSingletons方法是在ConfigurableListableBeanFactory接口中定义,由其子类DefaultListableBeanFactory实现。
1 // FactoryBean创建对象的实例名前缀 2 String FACTORY_BEAN_PREFIX = "&"; 3 4 // 实例化IOC容器的单例对象 5 public void preInstantiateSingletons() throws BeansException { 6 // 创建一个beanDefinitionNames的一个副本 7 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); 8 9 // 触发所有非延迟加载单例bean的初始化,遍历集合的对象 10 for (String beanName : beanNames) { 11 // 合并父级BeanDefinition 12 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); 13 // 条件判断,非抽象,单例,非懒加载 14 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { 15 // 判断是否实现了FactoryBean接口 16 if (isFactoryBean(beanName)) { 17 // 根据&+beanName来获取具体的对象 18 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); 19 // 类型转换处理 20 if (bean instanceof FactoryBean) { 21 FactoryBean<?> factory = (FactoryBean<?>) bean; 22 // 判断这个FactoryBean是否希望立即初始化 23 boolean isEagerInit; 24 if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { 25 isEagerInit = AccessController.doPrivileged( 26 (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, 27 getAccessControlContext()); 28 } 29 else { 30 isEagerInit = (factory instanceof SmartFactoryBean && 31 ((SmartFactoryBean<?>) factory).isEagerInit()); 32 } 33 // 如果希望急切的初始化,则通过beanName获取bean实例 34 if (isEagerInit) { 35 getBean(beanName); 36 } 37 } 38 } 39 // 如果beanName对应的bean不是FactoryBean,只是普通的bean,通过beanName获取bean实例 40 else { 41 getBean(beanName); 42 } 43 } 44 } 45 46 // 遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调 47 for (String beanName : beanNames) { 48 // 获取beanName对应的bean实例 49 Object singletonInstance = getSingleton(beanName); 50 // 判断singletonInstance是否实现了SmartInitializingSingleton接口 51 if (singletonInstance instanceof SmartInitializingSingleton) { 52 // 类型转换 53 SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; 54 // 触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法 55 if (System.getSecurityManager() != null) { 56 AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 57 smartSingleton.afterSingletonsInstantiated(); 58 return null; 59 }, getAccessControlContext()); 60 } 61 else { 62 smartSingleton.afterSingletonsInstantiated(); 63 } 64 } 65 } 66 }
1、获取所有的beanDefinition的名称集合beanNames ;
2、遍历beanNames集合,触发所有非延迟加载单例bean的初始化 ·根据beanName获取beanName合并后的本地RootBeanDefinition; ·若bean定义信息非抽象、为单例、并且为非懒加载的。 ·判断bean对象是否实现了FactoryBean接口。若实现了FactoyBean接口,将&+beanName作为新的bean名称,通过getBean获取FactoryBean类型的(&+beanName)对象实例,若FactoryBean是否需要及时初始化标识为true,则通过getBean(beanName)获取beanName的bean实例; ·若没有实现FactoryBean接口,只是普通的Bean, 通过getBean获取beanName的bean实例。 ·再次遍历beanNames集合,初始化bean实例的回调处理 ·通过beanName在三级缓存中获取对应的单例bean实例; ·单例bean实例实现了SmartInitializingSingleton接口,执行bean实例化后的回调处理。1.2、细节逻辑剖析
1、合并本地bean定义信息 - getMergedLocalBeanDefinition
getMergedLocalBeanDefinition是在抽象类AbstractBeanDefinition中实现的。1 // 已经合并的bean定义信息的缓存 2 private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<>(256); 3 4 // 获取beanName合并后的本地RootBeanDefinition 5 protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { 6 // 按照beanName从缓存mergedBeanDefinitions中获取beanName对应的RootBeanDefinition对象 7 RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); 8 // 如果mbd不为null 且 不需要重新合并定义 9 if (mbd != null && !mbd.stale) { 10 // 返回缓存中beanName对应的RootBeanDefinition 11 return mbd; 12 } 13 // 获取beanName对应的合并Bean定义,如果beanName对应的BeanDefinition是子BeanDefinition, 14 // 则通过与父级合并返回RootBeanDefinition 15 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 16 } 17 18 // 如果给定的beanDefinition是子beanDefinition,合并父级bean定义,返回RootBeanDefinition对象 19 protected RootBeanDefinition getMergedBeanDefinition( 20 String beanName, BeanDefinition bd, @Nullable BeanDefinition containingBd) 21 throws BeanDefinitionStoreException { 22 23 // 同步:使用从bean名称映射到合并的RootBeanDefinition集合进行加锁 24 synchronized (this.mergedBeanDefinitions) { 25 // 用于存储bd的MergedBeanDefinition 26 RootBeanDefinition mbd = null; 27 //该变量表示从bean名称映射到合并的RootBeanDefinition集合中取到的mbd且该mbd需要重新合并定义 28 RootBeanDefinition previous = null; 29 // 立即检查完全锁定,以强制执行相同的合并实例,如果没有包含bean定义 30 if (containingBd == null) { 31 // 从bean名称映射到合并的RootBeanDefinition集合中获取beanName对应的BeanDefinition作为mbd 32 mbd = this.mergedBeanDefinitions.get(beanName); 33 } 34 // 如果mbd为null或者mdb需要重新合并定义 35 if (mbd == null || mbd.stale) { 36 // 将mdn作为previous 37 previous = mbd; 38 // 如果获取不到原始BeanDefinition的父Bean名 39 if (bd.getParentName() == null) { 40 // 使用给定的RootBeanDefinition的副本,如果原始BeanDefinition是RootBeanDefinition对象 41 if (bd instanceof RootBeanDefinition) { 42 // 深拷贝一份bd的Bean定义赋值给mdb 43 mbd = ((RootBeanDefinition) bd).cloneBeanDefinition(); 44 } else { 45 // 创建一个新的RootBeanDefinition作为bd的深层副本并赋值给mbd 46 mbd = new RootBeanDefinition(bd); 47 } 48 } 49 else { 50 // 子bean定义:需要与父bean合并,定义一个父级BeanDefinition变量 51 BeanDefinition pbd; 52 try { 53 // 获取beanDefinition父级Bean对应的实际beanName (剔除'&'前缀、解析别名) 54 String parentBeanName = transformedBeanName(bd.getParentName()); 55 // 如果当前bean名不等于父级bean名 56 if (!beanName.equals(parentBeanName)) { 57 // 获取parentBeanName的"合并的"BeanDefinition赋值给pdb 58 pbd = getMergedBeanDefinition(parentBeanName); 59 } 60 // 如果父定义的beanName与bd的beanName相同,则拿到父BeanFactory, 61 // 只有在存在父BeanFactory的情况下,才允许父定义beanName与自己相同,否则就是将自己设置为父定义 62 else { 63 BeanFactory parent = getParentBeanFactory(); 64 // 如果父BeanFactory是ConfigurableBeanFactory,则通过父BeanFactory获取父定义的MergedBeanDefinition 65 if (parent instanceof ConfigurableBeanFactory) { 66 // 使用父工厂获取parentBeanName对应的合并BeanDefinition赋值给pdb 67 pbd = ((ConfigurableBeanFactory) parent).getMergedBeanDefinition(parentBeanName); 68 } 69 else { 70 // 如果父工厂不是ConfigurableBeanFactory,抛出没有此类bean定义异常,父级bean名为parentBeanName等于名为beanName的bean名; 71 // 没有AbstractBeanFactory父级无法解决 72 throw new NoSuchBeanDefinitionException(parentBeanName, 73 "Parent name '" + parentBeanName + "' is equal to bean name '" + beanName + 74 "': cannot be resolved without a ConfigurableBeanFactory parent"); 75 } 76 } 77 } 78 catch (NoSuchBeanDefinitionException ex) { 79 throw new BeanDefinitionStoreException(bd.getResourceDescription(), beanName, 80 "Could not resolve parent bean definition '" + bd.getParentName() + "'", ex); 81 } 82 // 使用父定义pbd构建一个新的RootBeanDefinition对象 83 mbd = new RootBeanDefinition(pbd); 84 // 使用原始bd定义信息覆盖父级的定义信息 85 mbd.overrideFrom(bd); 86 } 87 // 如果mbd之前没有配置过作用域,设置单例作用域 88 if (!StringUtils.hasLength(mbd.getScope())) { 89 mbd.setScope(SCOPE_SINGLETON); 90 } 91 // 非单例bean中包含的bean本身不能是单例。 92 // 因为这可能是外部bean的父子合并的结果,在这种情况下,原始内部bean定义将不会继承合并的外部bean的单例状态。 93 // 如果有传包含bean定义且包含bean定义不是单例但mbd又是单例 94 if (containingBd != null && !containingBd.isSingleton() && mbd.isSingleton()) { 95 // 让mbd的作用域设置为跟containingBd的作用域一样 96 mbd.setScope(containingBd.getScope()); 97 } 98 // 暂时缓存合并的bean定义(稍后可能仍会重新合并以获取元数据更正),如果没有传入包含bean定义 且 当前工厂是同意缓存bean元数据 99 if (containingBd == null && isCacheBeanMetadata()) { 100 //将beanName和mbd的关系添加到 从bean名称映射到合并的RootBeanDefinition集合中 101 this.mergedBeanDefinitions.put(beanName, mbd); 102 } 103 } 104 // 如果存在上一个从bean名称映射到合并的RootBeanDefinition集合中取出的mbd 105 // 且该mbd需要重新合并定义 106 if (previous != null) { 107 // 拿previous来对mdb进行重新合并定义 108 copyRelevantMergedBeanDefinitionCaches(previous, mbd); 109 } 110 // 返回MergedBeanDefinition 111 return mbd; 112 } 113 } 114 115 /** 116 * 复制相关的合并bean定义缓存,或者说拿previous来对mdb进行重新合并定义 117 * @param previous 118 * @param mbd 119 */ 120 private void copyRelevantMergedBeanDefinitionCaches(RootBeanDefinition previous, RootBeanDefinition mbd) { 121 // 如果其中一个为null,返回false,mbd和previous的当前Bean类名称相同,工厂bean名称相同,工厂方法名相同 122 if (ObjectUtils.nullSafeEquals(mbd.getBeanClassName(), previous.getBeanClassName()) && 123 ObjectUtils.nullSafeEquals(mbd.getFactoryBeanName(), previous.getFactoryBeanName()) && 124 ObjectUtils.nullSafeEquals(mbd.getFactoryMethodName(), previous.getFactoryMethodName())) { 125 // 获取mbd的目标类型 126 ResolvableType targetType = mbd.targetType; 127 // 获取previous的目标类型 128 ResolvableType previousTargetType = previous.targetType; 129 // 如果mdb的目标类型为null或者mdb的目标类型与previous的目标类型相同 130 if (targetType == null || targetType.equals(previousTargetType)) { 131 // 设置mbd的目标类型为previous的目标类型 132 mbd.targetType = previousTargetType; 133 // 设置mbd的工厂bean标记为previous的工厂bean标记 134 mbd.isFactoryBean = previous.isFactoryBean; 135 // 设置mbd的用于缓存给定bean定义的确定的Class为previous的用于缓存给定bean定义的确定的Class 136 mbd.resolvedTargetType = previous.resolvedTargetType; 137 // 设置mbd的工厂方法返回类型为previous的工厂方法返回类型 138 mbd.factoryMethodReturnType = previous.factoryMethodReturnType; 139 // 设置mbd的用于缓存用于自省的唯一工厂方法候选为previous的用于缓存用于自省的唯一工厂方法候选 140 mbd.factoryMethodToIntrospect = previous.factoryMethodToIntrospect; 141 } 142 } 143 }
1、根据beanName从mergedBeanDefinitions缓存中获取beanName对应的RootBeanDefinition对象,如果缓存中存在bean定义信息并且bean定义信息不需要重新合并定义,返回缓存中的对象;
2、若缓存中的对象不存在或者mbd需要重新定义,则合并父级BeanDefinition并返回RootBeanDefinition. ·若beanName的bd(beanDefinition)无pbd(父级BeanDefinition) ·如果原始的bd为rbd(RootBeanDefinition)类型,原始的bd深拷贝一份,作为副本 ·若原始的bd不为rbd类型,创建RootBeanDefinition对象,对原始bd对深深拷贝, ·若beanName的bd(beanDefinition)有pbd(父级BeanDefinition) ·获取父级bd对应的实际beanName类名称; ·若原始bd的beanName与父级pbd的beanName不一致,获取parentBeanName合并的BeanDefinition赋值给pbd; ·若原始bd的beanName与父级pbd的beanName一致,拿到父级BeanFactory,父级BeanFactory获取父级bd的MergedBeanDefinition。 ·使用pbd(parentBeanDefinition)构建RootBeanDefinition对象; ·使用原始bd覆盖pbd的信息。 1. 如果在给定的bean定义中指定,则将覆盖beanClass 2. 将始终从给定的bean定义中获取abstract,scope,lazyInit,autowireMode,dependencyCheck和dependsOn 3. 将给定bean定义中ConstructorArgumentValues,propertyValues,methodOverrides 添加到现有的bean定义中 4. 如果在给定的bean定义中指定,将覆factoryBeanName,factoryMethodName,initMethodName,和destroyMethodName 3、如果存在上一个从bean名称映射到合并的RootBeanDefinition集合中取出的mbd,并且该mbd需要重新合并定义 ·1. 设置mbd的目标类型为previous的目标类型 ·2. 设置mbd的工厂bean标记为previous的工厂bean标记 ·3. 设置mbd的用于缓存给定bean定义的确定的Class为previous的用于缓存给定bean定义的确定的Class ·4. 设置mbd的工厂方法返回类型为previous的工厂方法返回类型 ·5. 设置mbd的用于缓存用于自省的唯一工厂方法候选为previous的用于缓存用于自省的唯一工厂方法候选 4、返回设置完成的mbd2、getBean - 获取beanName
getBean是抽象类AbstractBeanDefinition中实现的。1 // 通过beanName获取bean实例 2 public Object getBean(String name) throws BeansException { 3 // 此方法是实际获取bean的方法,也是触发依赖注入的方法 4 return doGetBean(name, null, null, false); 5 }该方法时实例化单例对象的核心方法,核心方法 getBean -> doGetBean -> createBean -> doCreateBean,先做下了解,后续单独拿出一章节来分析。
3、getSingleton - 从缓存中获取bean实例
getSingleton是在抽象类AbstractBeanDefinition中实现的。1 // 一级缓存 2 private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256); 3 // 二级缓存 4 private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16); 5 // 三级缓存 6 private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); 7 8 // 通过beanName返回已注册的单例对象 9 @Nullable 10 protected Object getSingleton(String beanName, boolean allowEarlyReference) { 11 // 从一级缓存(存放完整的bean)中获取beanName对应的单例对象 12 Object singletonObject = this.singletonObjects.get(beanName); 13 // 如果一级缓存中没有,并且该beanName对应的单例bean正在创建中 14 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { 15 // 从早期单例对象缓存(存放已实例化未初始化的bean)中获取单例对象(之所以称为早期单例对象,是因为earlySingletonObjects里 16 // 的对象都是通过体提前曝光的ObjectFactory创建出来的,还未进行属性填充等操作) 17 singletonObject = this.earlySingletonObjects.get(beanName); 18 // 如果在早期单例对象缓存中也没有,并且允许创建早期单例对象引用 19 if (singletonObject == null && allowEarlyReference) { 20 //如果为空,则锁定全局变量并进行处理 21 synchronized (this.singletonObjects) { 22 // 双重检验锁 - DCL 23 singletonObject = this.singletonObjects.get(beanName); 24 if (singletonObject == null) { 25 singletonObject = this.earlySingletonObjects.get(beanName); 26 if (singletonObject == null) { 27 // 当某些方法需要提前初始化的时候则会调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories 28 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); 29 if (singletonFactory != null) { 30 // 如果存在单例对象工厂,则通过工厂创建一个单例对象 31 singletonObject = singletonFactory.getObject(); 32 // 记录在缓存中,二级缓存和三级缓存的对象不能同时存在 33 this.earlySingletonObjects.put(beanName, singletonObject); 34 // 从三级缓存中移除 35 this.singletonFactories.remove(beanName); 36 } 37 } 38 } 39 } 40 } 41 } 42 return singletonObject; 43 }根据beanName从缓存中获取对应的实例,引入一级、二级、三级缓存的概念。 1、一级缓存 - singletonObjects 单例对象的缓存,存放<beanname, beaninstance="">的键值对,存放完整的bean用于保存BeanName和创建bean实例之间的关系。 2、二级缓存 - earlySingletonObjects 存放提前暴露的Bean,Bean 是不完整的,未完成属性注入和执行 初始化(init) 方法,保存BeanName和创建bean实例之间的关系,与singletonFactories的不同之处在于,当一个单例bean被放到这里之后,那么当bean还在创建过程中就可以通过getBean方法获取到,可以方便进行循环依赖的检测。 3、三级缓存 - singletonFactories 存放的是 Bean 工厂,工厂的作用主要是生产 Bean存放到二级缓存中用于保存BeanName和创建bean的工厂之间的关系。 4、afterSingletonsInstantiated - bean实例化后的处理