前言
前面几章spring已经把需要的注册的bean的信息已经全部加载到了BeanFactory中了,那么之后要做的事儿当然就是进行实例化了,当然了可能有人会问为何不在加载到bean信息的时候直接进行实例化呢,这不还需要依赖注入嘛,当然是要所有的都加载完了才能实例化。ApplicationContext相对于BeanFactory来说,早期的BeanFactory受制于硬件配置,所以在我们需要某个bean的时候才会进行实例化。而ApplicationContext则会在一开始就将所有的注册的Bean(标记懒加载的,或者非单例加载除外)全部进行实例化。本文则主要介绍spring如何实例化bean,并且Bean的生命周期也会穿插其中。
这儿先放一张加载的大致流程图
从图中可以看到加正式加载的过程并不多,实例化->放入提前暴露容器->赋值完成后其实就算完成实例化了,但spring在其中穿插了 很多的BeanPostProcessor以及aware,同时也会根据所加载bean是否实现了InitializingBean接口来决定是否需要执行afterPropertiesSet方法。说明spring在实例化bean时给我们流下了足够的扩展空间。
正文
我们回到上下文的refresh方法中
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { ../代码略 try { postProcessBeanFactory(beanFactory); invokeBeanFactoryPostProcessors(beanFactory); // 注册所有BeanPostProcessors registerBeanPostProcessors(beanFactory); ../代码略 //实例化bean finishBeanFactoryInitialization(beanFactory); ../代码略 } ../代码略 } }
前面一篇我们成功的执行了invokeBeanFactoryPostProcessors方法,然后将所有的BeanFactoryPostProcessor后置方法执行了,然后也成功的将所有需要注册到容器的bean的BeanDefination也收集到了BeanFactory中。本文则主要关注后面两个方法。
- registerBeanPostProcessors 按照一定顺序注册BeanPostProcessor
- 实例化所有的bean
至于注册BeanPostProcessor较为简单,就是将系统所有的BeanPostProcessor按照顺序,即我们之前也遇到的三级顺序来添加,实现了PriorityOrdered为第一级,实现了Ordered为第二级,其他的为第三级。具体添加过程较为简单所以代码部分略过,我们直接看实例化bean的方法
1.finishBeanFactoryInitialization 实例化的入口
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化一个ConversionService 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)); } // 初始化一个默认的EmbeddedValueResolver(如果系统没有指定的话) if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // 实例化LoadTimeWeaverAware getBean方法会触发实例化 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); //实例化之前冻结配置 beanFactory.freezeConfiguration(); // 实例化所有非懒加载的实例 beanFactory.preInstantiateSingletons(); }
这儿就是做了一些必要的提前设置。这儿我们进入beanFactory.preInstantiateSingletons方法,注意这儿的beanFactory一般为DefaultListableBeanFactory,本系列第二章初始化应用上下文有讲到
2.preInstantiateSingletons
顾名思义,看方法名就知道是实例化之前的一些准备,看代码
@Override public void preInstantiateSingletons() throws BeansException { //打印下日志 if (this.logger.isDebugEnabled()) { this.logger.debug("Pre-instantiating singletons in " + this); } //迭代spring找到的所有需要注册的bean List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); //开始迭代 for (String beanName : beanNames) { //获取该bean对应的mergedBeanDefinition //如果没有则获取其父类的MergedLocalBeanDefinition //如果父类为空则创建RootBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //如果不是抽象类 且是单例构造 非懒加载 则实例化 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //如果该bean是FactoryBean if (isFactoryBean(beanName)) { //如果是FactoryBean则要判断下其是否需要提早初始化 Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; 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 { //非factoryBean 初始化 getBean(beanName); } } } // 如果为SmartInitializingSingleton类型 则执行下其初始化完成后的afterSingletonsInstantiated方法 for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
方法也就是获取我们之前得到的beanDefinitionNames,然后挨个遍历,如果其不为抽象类,且是单例加载,非延迟加载,那我们就对其进行实例化。然后根据beanName获取其合并的BeanDefinition,也就是其BeanDefinition一直递归加上其父类的BeanDefinition,最终合并为一个RootBeanDefinition并返回,具体的这儿的分析可以查看这篇博客。https://blog.csdn.net/andy_zhang2007/article/details/86514320
获取到合并的beanDefinition后,检查其是否满足加载的条件。这儿可以看出springboot满足初始化即加载的条件主要由两:单例记载,非懒加载。
然后会判断当前迭代的bean是否是FactoryBean,如果是则进行特殊判断处理下,这儿二者最终都会调用getBean方法来创建类。创建完成后如果该bean实现了SmartInitializingSingleton接口,则会执行下其afterSingletonsInstantiated方法。
其getBean方法是主要的创建方法,其实看到这儿也能发现。ApplicationContext方法的初始即实例化最终也是循环调用的BeanFactory的getBean方法。
3.getBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException { //获取beanName final String beanName = transformedBeanName(name); Object 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 + "'"); } } //直接拿出来并返回 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } //这儿则是创建流程 else { //重复声明时有可能出现此问题 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } //查看父BeanFactory是否已经有了 如果有的话则返回父BeanFactory中的实例 BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // Not found -> check parent. 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 { // No args -> delegate to standard getBean method. return parentBeanFactory.getBean(nameToLookup, requiredType); } } //标记该bean已经在开始被实例化 if (!typeCheckOnly) { markBeanAsCreated(beanName); } try { //获取合并BeanDefinition final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //检查下合并BeanDefinition 这儿主要检查是否为抽象类 checkMergedBeanDefinition(mbd, beanName, args); // 获取该bean的构造函数的参数 //如果该bean构造函数中依赖的参数中,有参数实例化也需要依赖该bean 那么直接报循环引用的错误 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); } } } // 如果为scope为sington 那么只创建一个 if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { 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); } // 如果为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); } //如果都不是 比如是自定义的 那就根据自定义的逻辑创建 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; } } // 如果有合适的Converter 那么执行下converter转换器的操作 返回转换后的实例 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.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; }
该方法内容较多,但可以分步看
- 判断是否已经创建中并能获取实例,如果可以就返回,否则下一步
- 判断一下重复加载的问题,然后查看父BeanFactory是否有该类,如果有则使用父类的getBean返回,否则下一步
- 判断下循环循环引用的问题,如果构造函数有参数,但不存在循环引用,则先实例化构造参数
- 最终根据bean的scope来确定不同的初始化方式
- 根据初始化完成后的bean来寻找是否有合适的converter,如果有则转换后返回,否则直接返回
这样拆开看发现也就是spring很常规的一个判断逻辑,由于不同scope只是创建的数量不一致,但是实例化bean是一致的,所以我们就直接看实例化singleton,也就是我们最常见的单例注册。
4.单例化代码的片段
上面的代码中,我们着重看下创建单例的代码片段。
if (mbd.isSingleton()) { //获取创建后的实例 sharedInstance = getSingleton(beanName, () -> { try { //回调函数创建bean return createBean(beanName, mbd, args); } catch (BeansException ex) { //出现异常则将其销毁 destroySingleton(beanName); throw ex; } }); //看当前的bean是一个普通的bean还是beanFactory //如果是普通的bean直接返回 //如果是factoryBean则返回其getObject方法的结果 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
这儿可以看到通过getSingletom方法获取bean,这个方法有个回调函数是用来创建bean的,可以得知具体创建bean的时机肯定是getSingleton中调用这个函数的时候。getSingletom则只是做了一些前后处理。那我们还是先看下回调函数中的createBean方法,毕竟这才是核心创建过程。
5.createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { //获取该bean的合并BeanDefinition RootBeanDefinition mbdToUse = mbd; //查看当前RootBeanDefinition是否已经有resolveBeanClass 如果有的话直接clone一个beanDefinition Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } //检查下所有的override方法 try { mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // 执行所有实现了InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法 // 这儿如果返回不为null 则就是自定义了返回的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); } try { //执行doCreateBean创建bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } ../代码省略 }
该方法内部照例做了一下准备,其中有个方法需要注意resolveBeforeInstantiation ,该方法会在实例化之前执行所有实现了InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法,如果返回值不为空则代表自定义了类实例化过程,这样会直接返回bean而不会进行下面的所有操作。
然后执行doCreateBean创建实例对象。
6.doCreateBean
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { // 实例化bean 如果factoryBeanInstance已经有了则将其remove掉 BeanWrapper instanceWrapper = null; if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } if (instanceWrapper == null) { //创建实例 instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = instanceWrapper.getWrappedInstance(); Class<?> beanType = instanceWrapper.getWrappedClass(); //检查下创建出来的bean是否为null,例如我们从beanFactory中get为null 或者@Bean方法返回为null if (beanType != NullBean.class) { mbd.resolvedTargetType = beanType; } // 执行所有实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法 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; } } //如果允许属性值循环依赖,则将实例其放入一个singletonFactories缓存中,此时该类已经实例化但还未为属性赋值 //如果该类依赖的属性值实例化时依赖该类,那么就可以从这个singletonFactories提前拿到还未赋值的属性值实例 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, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { // 为实例赋属性值 populateBean(beanName, mbd, instanceWrapper); //执行一些列初始化方法 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 " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // 如果bean是一次性的则将其注入一次性使用容器中 try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
该方法有几个地方需要注意
- 实例化bean后检查了该bean是否为null
- 执行了所有实现了实现了MergedBeanDefinitionPostProcessor接口的类的postProcessMergedBeanDefinition方法
- 如果出现了属性值循环引用,且允许循环引用,那么会将实例化好但还未赋值的bean放入一个singletonFactories提前暴露容器中来解决属性值循环引用
- 然后在为属性赋值
- 然后执行初始化方法。
我们则简要分析下这几个步骤
6.1createBeanInstance创建实例
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 确保beanClass可以被实例化 例如其是否为public 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 如果有直接返回 Supplier<?> instanceSupplier = mbd.getInstanceSupplier(); if (instanceSupplier != null) { return obtainFromSupplier(instanceSupplier, beanName); } //查看该类是否为@Bean方法初始化 如果是的话执行方法逻辑 if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... boolean resolved = false; boolean autowireNecessary = false; //如果初始化构造参数为null且能找到构造函数或者FactoryMethod(如果为factoryBean) if (args == null) { synchronized (mbd.constructorArgumentLock) { if (mbd.resolvedConstructorOrFactoryMethod != null) { resolved = true; //查看其是否有@Autowired的参数 autowireNecessary = mbd.constructorArgumentsResolved; } } } if (resolved) { //如果有@Autowaired参数则执行这个autowireConstructor方法 if (autowireNecessary) { return autowireConstructor(beanName, mbd, null, null); } //如果没有则执行instantiateBean方法 else { return instantiateBean(beanName, mbd); } } //如果上面没找到有效的构造函数 就从BeanPostProcessor中查找 然后执行返回 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); }
这儿步骤主要为
1.校验是否能实例化
2.是否有定制的supplier,有则返回
3.是否为@Bean初始化,如果是则执行专门的实例化方法
4.如果传入的构造参数为null,则根据自动注入的参数或者无参的方法来实例化。
5.如果传入的参数不为null 或者需要的参数里有不是自动注入的,那么根据BeanPostProcessor找到合适的构造函数并实例化
这儿具体的对象创建过程由于篇幅就不讲解了,可以根据各个方法进去仔细查看,不过大概能想到的应该就是根据传入的参数反射创建实例,如果是@Bean方法创建的话应该是反射执行方法创建,如果需要代理的话则创建代理对象并返回。
6.2 applyMergedBeanDefinitionPostProcessors
这也是springBean生命周期中的一个重要步骤
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof MergedBeanDefinitionPostProcessor) { MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp; bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName); } } }
该方法会执行所有的MergedBeanDefinitionPostProcessor 的postProcessMergedBeanDefinition方法。
6.3 处理属性值循环引用addSingletonFactory
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
这儿注意getEarlyBeanReference又会执行所有实现了SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
此处其实就是利用了一个提前暴露的singletonFactories容器,将实例化但还未赋值的bean放置在其中,当循环引用的bean需要用到这个bean时就可以拿到还未赋值的bean。即可解决属性值循环引用的问题。
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(singletonFactory, "Singleton factory must not be null"); synchronized (this.singletonObjects) { if (!this.singletonObjects.containsKey(beanName)) { this.singletonFactories.put(beanName, singletonFactory); //singletonFactories 提前暴露的Factories容器 this.earlySingletonObjects.remove(beanName);//singletonFactories 提前暴露的bean容器 this.registeredSingletons.add(beanName);// 已注册的单例容器 } } }
注意这儿有两个容器都涉及到提前引用 ,区别是earlySingletonObjects 放置的实例化的bean 而singletonFactories 放置的是实例化的bean的包装。之所以加个包装是为了获取提前暴露的引用时可以执行SmartInstantiationAwareBeanPostProcessor接口的getEarlyBeanReference方法。
/** Cache of singleton factories: bean name --> ObjectFactory */ private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16); /** Cache of early singleton objects: bean name --> bean instance */ private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
具体的处理循环引用的逻辑文章最后会单独说下,这儿注意get
6.4 为属性赋值
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; } } //检查下是否需要赋值 如果有某个InstantiationAwareBeanPostProcessor返回未false 那么就跳过赋值操作 boolean continueWithPropertyPopulation = true; if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) { continueWithPropertyPopulation = false; break; } } } } if (!continueWithPropertyPopulation) { return; } //获取要赋值的属性值 PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null); //根据不同的来不同的注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); // by name 例如@Resources if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } // by type 例如@Autowied 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); //如果有对应的InstantiationAwareBeanPostProcessors则执行下其postProcessPropertyValues方法 if (hasInstAwareBpps || needsDepCheck) { if (pvs == null) { pvs = mbd.getPropertyValues(); } PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching); if (hasInstAwareBpps) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName); if (pvs == null) { return; } } } } if (needsDepCheck) { checkDependencies(beanName, mbd, filteredPds, pvs); } } if (pvs != null) { //将找到的属性值赋上 applyPropertyValues(beanName, mbd, bw, pvs); } }
该方法检查了下bean是否为空,和该bean是否需要赋值,然后找到了所有的InstantiationAwareBeanPostProcessor执行了下其postProcessPropertyValues (如果需要的话),最后将找到的值赋上。
6.5 初始化方法initializeBean
bean实例化后会执行initializeBean方法。该方法会执行很多bean生命周期相关的方法。
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { invokeAwareMethods(beanName, bean); return null; }, getAccessControlContext()); } else { //1.执行所有实现了BeanNameAware的setBeanName方法 //2.执行所有实现了BeanClassLoaderAware的setBeanClassLoader方法 //3.执行所有实现了BeanFactoryAware的setBeanFactory方法 invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { //执行所有实现了BeanPostProcessor的postProcessBeforeInitialization方法 wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { //如果该类实现了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; }
该方法会执行很多的spring生命周期的方法,首先会执行一堆的aware前置方法。然后执行BeanPostProcessor的postProcessBeforeInitialization,然后如果该类实现了InitializingBean则执行afterPropertiesSet方法,最后执行BeanPostProcessor的postProcessAfterInitialization方法。此时创建bean的工作已经基本完成了。
7.回到getSingleton
上面所讲的都是ObjectFactory的回调函数的实现内容,那么调用的时机,和调用的前后逻辑还需要我们了解一下。即本文第4节的getSingtone方法。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //看下singletonObject中是否已经有了 如果没有进入创建 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 + "'"); } //将当前bean加入singletonsCurrentlyInCreation容器 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { //执行回调函数的创建逻辑 singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. 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; } //从singletonsCurrentlyInCreation容器中移除该bean afterSingletonCreation(beanName); } if (newSingleton) { //将该bean添加到singletonObjects容器中 并从提前暴露的容器中移除 addSingleton(beanName, singletonObject); } } return singletonObject; } }
可以看到该类中主要核查防止了重复加载,然后通过回调函数获取我们创建的bean后,将其从提前暴露的容器中移除,然后放入BeanFactory的真正的bean容器中。此时一个bean就算被创建完成已经可以正式使用了。
可以发现其中执行了很多的BeanPostProcessor和aware,这也是spring对bean的扩展性做的极高的一种体现。
到此spring初始化一个bean已经成功了。有关spring的具体加载流程简要图已经在一开始给出,可以对照着查看。
后记
关于spring解决属性循环依赖的问题主要是如下的代码。
protected Object getSingleton(String beanName, boolean allowEarlyReference) { //如果未从singletonObjects获取到就要尝试从提前暴露的容器中拿 Object singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { //从提前暴露的容器中拿singletonObject singletonObject = this.earlySingletonObjects.get(beanName); //如果也为空 if (singletonObject == null && allowEarlyReference) { //那么尝试从提前暴露的包装容器中拿 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); if (singletonFactory != null) { //如果包装容器不为空,那么就拿到其引用 然后添加到提前暴露容器中 并从提前暴露的包装容器中移除 singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } return singletonObject; }
可以看到在获取bean时如果没获取到会尝试从提前暴露容器中获取,如果还是获取不到就从提前暴露的包装容器中获取。如果能获取到就将其从包装容器中移除,设置到容器中