Spring源码解析之八finishBeanFactoryInitialization办法即初始化单例bean
七千字长文粗浅解读,Spirng中是如何初始化单例bean的,和面试中最常问的Spring是如何解决循环依赖?
明天解读Spring外围办法refresh()中最最重要的一个办法finishBeanFactoryInitialization()办法,该办法负责初始化所有的单例bean。
finishBeanFactoryInitialization()办法位于refresh()中下标为8的地位。
到目前为止,应该说 BeanFactory 曾经创立实现,并且所有的实现了 BeanFactoryPostProcessor 接口的 Bean 都曾经初始化并且其中的 postProcessBeanFactory(factory) 办法曾经失去回调执行了。而且 Spring 曾经“手动”注册了一些非凡的 Bean,如 environment
、systemProperties
等。
剩下的就是初始化 singleton beans 了,大都数咱们的业务中都是单例bean,就像咱们写的@Controller、@Service的类(没有设置懒加载的)都是在这个中央初始化,以供咱们应用,如果没有设置懒加载,那么 Spring 会在接下来初始化所有的 singleton beans。
咱们先看一下refresh()的源码,大略看下finishBeanFactoryInitialization(beanFactory)所处的地位。
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. //1、刷新前的筹备 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. //2、将会初始化 BeanFactory、加载 Bean、注册 Bean ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. //3、设置 BeanFactory 的类加载器,增加几个 BeanPostProcessor,手动注册几个非凡的 bean prepareBeanFactory(beanFactory); try { //4、模板办法 // Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. //执行BeanFactory后置处理器 invokeBeanFactoryPostProcessors(beanFactory); // 5、Register bean processors that intercept bean creation. //注册bean后置处理器 registerBeanPostProcessors(beanFactory); // Initialize message source for this context. //国际化 initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. //6、模板办法--springboot实现了这个办法 onRefresh(); // Check for listener beans and register them. //7、注册监听器 registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //8、实现bean工厂的初始化**办法重要********************************************** finishBeanFactoryInitialization(beanFactory); //9、 Last step: publish corresponding event. finishRefresh(); }
咱们深刻finishBeanFactoryInitialization(beanFactory)中,外面的调用线路盘根错节,还望读者能够做好心理准备。
/** * 负责单例bean的初始化 * Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. */ protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // Initialize conversion service for this context. //最先初始化名字为 conversionService的类,conversionService类 它用来将前端传过来的参数和后端的 controller 办法上的参数进行绑定的时候用 //尤其是用于非根底类型的转换 if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( //初始化在getBean()办法中实现 beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // Register a default embedded value resolver if no bean post-processor // (such as a PropertyPlaceholderConfigurer bean) registered any before: // at this point, primarily for resolution in annotation attribute values. if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 先初始化 LoadTimeWeaverAware 类型的 Bean aop相关注:大略有个印象,当前解析aop会和它串起来。 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. //freeze的单词意思是解冻,这个时候曾经开始预初始化, bean 定义解析、加载、注册先进行 beanFactory.freezeConfiguration(); // Instantiate all remaining (non-lazy-init) singletons. //开始初始化 beanFactory.preInstantiateSingletons(); }
该办法是判断bean的一系列是不是属于某个类型的bean,如果是就调用getBean()办法,如果不是,就调用beanFactory.preInstantiateSingletons()进行初始化,咱们先把getBean()放一放,重点看一看beanFactory.preInstantiateSingletons()办法。
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. // this.beanDefinitionNames 保留了所有的 beanNames List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... //// 上面这个循环,触发所有的非懒加载的 singleton beans 的初始化操作 for (String beanName : beanNames) { RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 非形象、非懒加载的 singletons。如果配置了 'abstract = true',那是不须要初始化的 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 解决 FactoryBean (负责初始化工厂的bean) if (isFactoryBean(beanName)) { // FactoryBean 的话,在 beanName 后面加上 ‘&’ 符号 //此处调用getBean()办法 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { FactoryBean<?> factory = (FactoryBean<?>) bean; // 判断以后 FactoryBean 是否是 SmartFactoryBean 的实现 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged( (PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // 对于一般的 Bean,只有调用 getBean(beanName) 这个办法就能够进行初始化了 getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... // 到这里阐明所有的非懒加载的 singleton beans 曾经实现了初始化 // 如果咱们定义的 bean 是实现了 SmartInitializingSingleton 接口的,那么在这里失去回调 //如果你想在单例bean初始化后做一些事 那就实现该接口 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
preInstantiateSingletons()办法的次要工作是进行初始化的,在初始化前同样是一系列判断,如,是否是懒加载的,是否是一个factorybean(一个特地的bean,负责工厂创立的bean),最初调用getBean()办法。
其中有个插曲是否实现了SmartInitializingSingleton接口,将接口让你能够在bean初始化后做一些事,咱们写一个简略的实例测试一下。
其余中央读者看正文理解一下即可,咱们开始持续深刻getBean()办法。
getBean()办法外部调用了doGetBean()咱们间接看doGetBean办法。
// 咱们在分析初始化 Bean 的过程,然而 getBean 办法咱们常常是用来从容器中获取 Bean 用的,留神切换思路, // 曾经初始化过了就从容器中间接返回,否则就先初始化再返回 protected <T> T doGetBean( String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly) throws BeansException { // 获取一个 “正统的” beanName,解决两种状况,一个是后面说的 FactoryBean(后面带 ‘&’), // 一个是别名问题,因为这个办法是 getBean,获取 Bean 用的,你要是传一个别名进来,是齐全能够的 String beanName = transformedBeanName(name); // 返回值 Object bean; // Eagerly check singleton cache for manually registered singletons. // 查看下是不是曾经创立过了 Object sharedInstance = getSingleton(beanName); // 这里说下 args ,尽管看上去一点不重要。后面咱们一路进来的时候都是 getBean(beanName), // 所以 args 传参其实是 null 的,然而如果 args 不为空的时候,那么意味着调用方不是心愿获取 Bean,而是创立 Bean 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 的话,间接返回 sharedInstance, // 如果是 FactoryBean 的话,返回它创立的那个实例对象 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. // 创立过了此 beanName 的 prototype 类型的 bean,那么抛异样, // 往往是因为陷入了循环援用 哦,原来之前的循环依赖都是在这抛的异样,再有问题就不是无头苍蝇了 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. // 检查一下这个 BeanDefinition 在容器中是否存在 BeanDefinition既是蕴含了bean的一系列信息 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. // 如果以后容器不存在这个 BeanDefinition,试试父容器中有没有 String nameToLookup = originalBeanName(name); if (parentBeanFactory instanceof AbstractBeanFactory) { return ((AbstractBeanFactory) parentBeanFactory).doGetBean( nameToLookup, requiredType, args, typeCheckOnly); } else if (args != null) { // Delegation to parent with explicit args. // 返回父容器的查问后果 return (T) parentBeanFactory.getBean(nameToLookup, args); } else if (requiredType != null) { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } else { return (T) parentBeanFactory.getBean(nameToLookup); } } if (!typeCheckOnly) { // typeCheckOnly 为 false,将以后 beanName 放入一个 alreadyCreated 的 Set 汇合中。 markBeanAsCreated(beanName); } /* * 稍稍总结一下: * 到这里的话,要筹备创立 Bean 了,对于 singleton 的 Bean 来说,容器中还没创立过此 Bean; * 对于 prototype 的 Bean 来说,原本就是要创立一个新的 Bean。 */ try { RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // Guarantee initialization of beans that the current bean depends on. // 先初始化依赖的所有 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 + "'"); } // 注册一下依赖关系 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, () -> { try { // 执行创立 Bean,详情持续深刻 // 第三个参数 args 数组代表创立实例须要的参数,不就是给构造方法用的参数,或者是工厂 Bean 的参数嘛,不过要留神,在咱们的初始化阶段,args 是 null。 // 这回咱们要到一个新的类了 AbstractAutowireCapableBeanFactory,看类名,AutowireCapable?类名是不是也阐明了点问题了。 // 次要是为了以下场景,采纳 @Autowired 注解注入属性值: 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); // 执行创立 Bean prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { String scopeName = mbd.getScope(); if (!StringUtils.hasLength(scopeName)) { throw new IllegalStateException("No scope name defined for bean ´" + beanName + "'"); } 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; }
具体的实例化过程在createBean()办法中,咱们持续深刻createBean()办法。
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isTraceEnabled()) { logger.trace("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. // 确保 BeanDefinition 中的 Class 被加载 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // Prepare method overrides. // 筹备办法覆写,这里又波及到一个概念:MethodOverrides,它来自于 bean 定义中的 <lookup-method /> // 和 <replaced-method />,如果读者感兴趣,回到 bean 解析的中央看看对这两个标签的解析。 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. // 让 InstantiationAwareBeanPostProcessor 在这一步有机会返回代理, // 在 《Spring AOP 源码剖析》那篇文章中有解释,这里先跳过 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); } try { // 重头戏,创立 bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled()) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) { // A previously detected exception with proper bean creation context already, // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry. throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
咱们持续往里看 doCreateBean 这个办法,这个调用过程是真的深。
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { // Instantiate the bean. BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { // 阐明不是 FactoryBean,这里实例化 Bean,这里十分要害,细节之后再说********** instanceWrapper = createBeanInstance(beanName, mbd, args); } Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // Allow post-processors to modify the merged bean definition. 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. // 上面这块代码是为了解决循环依赖的问题,这是个重头戏,解决循环依赖问题 boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName)); if (earlySingletonExposure) { if (logger.isTraceEnabled()) { logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references"); } addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } // Initialize the bean instance. Object exposedObject = bean; try { // 这一步也是十分要害的,这一步负责属性拆卸,因为后面的实例只是实例化了,并没有设值,这里就是设值*************** populateBean(beanName, mbd, instanceWrapper); // 还记得 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); } } // 上面这块代码是为了解决循环依赖的问题,这是个重头戏,解决循环依赖问题 if (earlySingletonExposure) { //循环依赖的外围办法调用 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(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 " + "'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
到这里,咱们曾经剖析完了 doCreateBean 办法,总的来说,咱们曾经说完了整个初始化流程。
在实例化bean后有一个特地重要的知识点,也是面试中最常问的,Spring怎么解决循环依赖问题?外围代码就在这个办法外面。
循环依赖其实就是循环援用,也就是两个或则两个以上的bean相互持有对方,最终造成闭环。比方A依赖于B,B依赖于C,C又依赖于A。如下图:
doCreateBean 办法有三个外围流程。
(1)createBeanInstance:实例化,其实也就是调用对象的构造方法实例化对象
(2)populateBean:填充属性,这一步次要是多bean的依赖属性进行填充
(3)initializeBean:调用spring xml中的init 办法。
从下面讲述的单例bean初始化步骤咱们能够晓得,循环依赖次要产生在第一、第二步。也就是结构器循环依赖和field循环依赖。
那么咱们要解决循环援用也应该从初始化过程着手,对于单例来说,在Spring容器整个生命周期内,有且只有一个对象,所以很容易想到这个对象应该存在Cache中,Spring为了解决单例的循环依赖问题,应用了三级缓存。
咱们看一下getSingleton办法。
该办法还依赖于三个map,这三个map就是三级缓存。
/** Cache of singleton objects: bean name to bean instance. *///单例对象的cacheprivate final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** Cache of singleton factories: bean name to ObjectFactory. */// 单例对象工厂的cacheprivate final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** Cache of early singleton objects: bean name to bean instance. *///提前曝光的单例对象的Cacheprivate final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
@Nullable protected Object getSingleton(String beanName, boolean allowEarlyReference) { // Quick check for existing instance without full singleton lock Object singletonObject = this.singletonObjects.get(beanName); //判断以后单例bean是否正在创立中,也就是没有初始化实现(比方A的结构器依赖了B对象所以得先去创立B对象 // 或则在A的populateBean过程中依赖了B对象,得先去创立B对象,这时的A就是处于创立中的状态。 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { singletonObject = this.earlySingletonObjects.get(beanName); // 是否容许从singletonFactories中通过getObject拿到对象 if (singletonObject == null && allowEarlyReference) { synchronized (this.singletonObjects) { // Consistent creation of early reference within full singleton lock singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { singletonObject = this.earlySingletonObjects.get(beanName); if (singletonObject == null) { ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } } } return singletonObject; }
剖析getSingleton()的整个过程,Spring首先从一级缓存singletonObjects中获取。如果获取不到,并且对象正在创立中,就再从二级缓存earlySingletonObjects中获取。
如果还是获取不到且容许singletonFactories通过getObject()获取,就从三级缓存singletonFactory.getObject()(三级缓存)获取,如果获取到了则:
this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName);
从singletonFactories中移除,并放入earlySingletonObjects中。其实也就是从三级缓存挪动到了二级缓存。
从下面三级缓存的剖析,咱们能够晓得,Spring解决循环依赖的窍门就在于singletonFactories这个三级cache。
里就是解决循环依赖的要害,这段代码产生在createBeanInstance之后,也就是说单例对象此时曾经被创立进去(调用了结构器)。这个对象曾经被生产进去了,尽管还不完满(还没有进行初始化的第二步和第三步),然而曾经能被人认出来了(依据对象援用能定位到堆中的对象),所以Spring此时将这个对象提前曝光进去让大家意识,让大家应用。
这样做有什么益处呢?
让咱们来剖析一下“A的某个field或者setter依赖了B的实例对象,同时B的某个field或者setter依赖了A的实例对象”这种循环依赖的状况。
A首先实现了初始化的第一步,并且将本人提前曝光到singletonFactories中,此时进行初始化的第二步,发现自己依赖对象B,此时就尝试去get(B),发现B还没有被create,所以走create流程,B在初始化第一步的时候发现自己依赖了对象A,于是尝试get(A),尝试一级缓存singletonObjects(必定没有,因为A还没初始化齐全),尝试二级缓存earlySingletonObjects(也没有),尝试三级缓存singletonFactories,因为A通过ObjectFactory将本人提前曝光了,所以B可能通过ObjectFactory.getObject拿到A对象(尽管A还没有初始化齐全,然而总比没有好呀),B拿到A对象后顺利完成了初始化阶段1、2、3,齐全初始化之后将本人放入到一级缓存singletonObjects中。
此时返回A中,A此时能拿到B的对象顺利完成本人的初始化阶段2、3,最终A也实现了初始化,进去了一级缓存singletonObjects中,而且更加侥幸的是,因为B拿到了A的对象援用,所以B当初hold住的A对象实现了初始化。
晓得了这个原理时候,必定就晓得为啥Spring不能解决“A的构造方法中依赖了B的实例对象,同时B的构造方法中依赖了A的实例对象”这类问题了!因为退出singletonFactories三级缓存的前提是执行了结构器,所以结构器的循环依赖没法解决。
接下来咱们挑 doCreateBean 中的三个细节进去说说。一个是创立 Bean 实例的 createBeanInstance 办法,一个是依赖注入的 populateBean 办法,还有就是回调办法 initializeBean。
这三个办法也是极其简单的,读者有趣味能够持续的深刻进去。
1、 createBeanInstance 办法
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable 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()); } Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } if (mbd.getFactoryMethodName() != null) { // 采纳工厂办法实例化,不相熟这个概念的读者请看附录,留神,不是 FactoryBean return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... // 如果不是第一次创立,比方第二次创立 prototype bean。 // 这种状况下,咱们能够从第一次创立晓得,采纳无参构造函数,还是构造函数依赖注入 来实现实例化 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); } } // Candidate constructors for autowiring? // 判断是否采纳有参构造函数 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { // 构造函数依赖注入 return autowireConstructor(beanName, mbd, ctors, args); } // Preferred constructors for default construction? ctors = mbd.getPreferredConstructors(); if (ctors != null) { // 构造函数依赖注入 return autowireConstructor(beanName, mbd, ctors, null); } // No special handling: simply use no-arg constructor. // 调用无参构造函数 return instantiateBean(beanName, mbd); }
看一下instantiateBean办法是怎么做的。
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { Object beanInstance; if (System.getSecurityManager() != null) { beanInstance = AccessController.doPrivileged( (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this), getAccessControlContext()); } else { // 实例化 beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this); } // 包装一下,返回 BeanWrapper bw = new BeanWrapperImpl(beanInstance); initBeanWrapper(bw); return bw; } catch (Throwable ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex); } }
咱们能够看到,要害的中央在于:beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
外面是具体是实例化过程,咱们进去看看。
@Override public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) { // Don't override the class with CGLIB if no overrides. // 如果不存在办法覆写,那就应用 java 反射进行实例化,否则应用 CGLIB, // 办法覆写 请参见附录"办法注入"中对 lookup-method 和 replaced-method 的介绍 if (!bd.hasMethodOverrides()) { Constructor<?> constructorToUse; synchronized (bd.constructorArgumentLock) { constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod; if (constructorToUse == null) { final Class<?> clazz = bd.getBeanClass(); if (clazz.isInterface()) { throw new BeanInstantiationException(clazz, "Specified class is an interface"); } try { if (System.getSecurityManager() != null) { constructorToUse = AccessController.doPrivileged( (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor); } else { constructorToUse = clazz.getDeclaredConstructor(); } bd.resolvedConstructorOrFactoryMethod = constructorToUse; } catch (Throwable ex) { throw new BeanInstantiationException(clazz, "No default constructor found", ex); } } } // 利用构造方法进行实例化 return BeanUtils.instantiateClass(constructorToUse); } else { // Must generate CGLIB subclass. // 存在办法覆写,利用 CGLIB 来实现实例化,须要依赖于 CGLIB 生成子类,这里就不开展了。 // tips: 因为如果不应用 CGLIB 的话,存在 override 的状况 JDK 并没有提供相应的实例化反对 return instantiateWithMethodInjection(bd, beanName, owner); } }
到这里,咱们就算实例化实现了。咱们开始说怎么进行属性注入。
2、populateBean 办法
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { if (bw == null) { if (mbd.hasPropertyValues()) { 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. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { return; } } } } // bean 实例的所有属性都在这里了 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); int resolvedAutowireMode = mbd.getResolvedAutowireMode(); // 通过名字找到所有属性值,如果是 bean 依赖,先初始化依赖的 bean。记录依赖关系 if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // Add property values based on autowire by name if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // Add property values based on autowire by type if applicable. if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) { autowireByType(beanName, mbd, bw, newPvs); } pvs = newPvs; } boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors(); boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE); PropertyDescriptor[] filteredPds = null; if (hasInstAwareBpps) { if (pvs == null) { pvs = mbd.getPropertyValues(); } for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } // 这里有个十分有用的 BeanPostProcessor 进到这里: AutowiredAnnotationBeanPostProcessor // 对采纳 @Autowired、@Value 注解的依赖进行设值,这里的内容也是十分丰盛的 pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvsToUse == null) { return; } } pvs = pvsToUse; } } } if (needsDepCheck) { if (filteredPds == null) { filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); } checkDependencies(beanName, mbd, filteredPds, pvs); } if (pvs != null) { // 设置 bean 实例的属性值 applyPropertyValues(beanName, mbd, bw, pvs); } }
属性注入实现后,这一步其实就是解决各种回调了,这块代码比较简单。
3、 initializeBean办法
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { // 如果 bean 实现了 BeanNameAware、BeanClassLoaderAware 或 BeanFactoryAware 接口,回调 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { // BeanPostProcessor 的 postProcessBeforeInitialization 回调 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { // 解决 bean 中定义的 init-method, // 或者如果 bean 实现了 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 回调 //BeanPostProcessor 的两个回调都产生在这边,只不过两头解决了 init-method wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
自此,Spring实例化单例非懒加载bean的过程也就实现了,这也是Spirng最最重要的办法了。在咱们的日常应用Spring中,定义好各个类,而后在下面加上,@Controller,@Service,Autowired等注解,这些注解是怎么起作用的呢?
想必大部分同学都是知其然,不知其所以然,想必通过本文,读者心中能有一个分明的意识。