🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
[TOC] <br/> <br/> ![](https://i.loli.net/2019/03/13/5c88eb1c4cc26.png) > `getBean()`创建单例bean实例 * `getBean`调用`getSingleton(beanName, ObjectFactory)`,匿名工厂类中的`getObject()`方法调用了`creatBean()`。 * 对于已实例化好的单例`bean`,`getBean(String)`方法并不会再一次去创建,而是从缓存中获取。如果缓存中没有则根据`bean`的配置信息去创建这个`bean`。 ``` public T doGetBean(...) { // ... if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { //调用creatBean方法 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } //... ``` <br/> > ### `getSingleton(String, ObjectFactory)`方法 ``` public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' must not be null"); synchronized (this.singletonObjects) { // 从缓存中获取单例 bean,若不为空,则直接返回,不用再初始化 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } /* * 将 beanName 添加到 singletonsCurrentlyInCreation 集合中, * 用于表明 beanName 对应的 bean 正在创建中 */ beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { // 通过 getObject 方法调用 createBean 方法创建 bean 实例 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } // 将 beanName 从 singletonsCurrentlyInCreation 移除 afterSingletonCreation(beanName); } if (newSingleton) { /* * 将 <beanName, singletonObject> 键值对添加到 singletonObjects 集合中, * 并从其他集合(比如 earlySingletonObjects)中移除 singletonObject 记录 */ addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } } ``` <br/> > ### `createBean `方法 ``` protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // 解析 bean 的类型 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { // 处理 lookup-method 和 replace-method 配置,Spring 将这两个配置统称为 override method mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 在 bean 初始化前应用后置处理,如果后置处理返回的 bean 不为空,则直接返回 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } // 调用 doCreateBean 创建 bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } ``` <br/> > ### `doCreateBean `方法 ``` protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { // BeanWrapper 包装bean实例 //通过 BeanWrapper 的实现类可以方便的设置/获取 bean 实例的属性 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { // 从缓存中获取 BeanWrapper,并清理相关记录 instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { /* * 创建 bean 实例,并将实例包裹在 BeanWrapper 实现类对象中返回。createBeanInstance * 中包含三种创建 bean 实例的方式: * 1. 通过工厂方法创建 bean 实例 * 2. 通过构造方法自动注入(autowire by constructor)的方式创建 bean 实例 * 3. 通过无参构造方法方法创建 bean 实例 * * 若 bean 的配置信息中配置了 lookup-method 和 replace-method,则会使用 CGLIB * 增强 bean 实例。 */ instanceWrapper = createBeanInstance(beanName, mbd, args); } // 此处的 bean 可以认为是一个原始的 bean 实例,暂未填充属性 final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; // 这里又遇到后置处理了,此处的后置处理是用于处理已“合并的 BeanDefinition”。关于这种后置处理器具体的实现细节就不深入理解了,大家有兴趣可以自己去看 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; } } 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"); } // 添加工厂对象到 singletonFactories 缓存中 addSingletonFactory(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { // 获取早期 bean 的引用,如果 bean 中的方法被 AOP 切点所匹配到,此时 AOP 相关逻辑会介入 return getEarlyBeanReference(beanName, mbd, bean); } }); } Object exposedObject = bean; try { // 向 bean 实例中填充属性,populateBean 方法也是一个很重要的方法,后面会专门写文章分析 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { /* * 进行余下的初始化工作,详细如下: * 1. 判断 bean 是否实现了 BeanNameAware、BeanFactoryAware、 * BeanClassLoaderAware 等接口,并执行接口方法 * 2. 应用 bean 初始化前置操作 * 3. 如果 bean 实现了 InitializingBean 接口,则执行 afterPropertiesSet * 方法。如果用户配置了 init-method,则调用相关方法执行自定义初始化逻辑 * 4. 应用 bean 初始化后置操作 * * 另外,AOP 相关逻辑也会在该方法中织入切面逻辑,此时的 exposedObject 就变成了 * 一个代理对象了 */ 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); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { // 若 initializeBean 方法未改变 exposedObject 的引用,则此处的条件为 true。 if (exposedObject == 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."); } } } } try { // 注册销毁逻辑 registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; } ``` <br/> <br/> *** > ### 参考 #### [Spring-IOC-容器源码分析-创建单例-bean](http://www.tianxiaobo.com/2018/06/04/Spring-IOC-%E5%AE%B9%E5%99%A8%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90-%E5%88%9B%E5%BB%BA%E5%8D%95%E4%BE%8B-bean/)