(一)Spring IoC源码-2.bean的加载-04创建bean

xiaoxiao2021-02-28  49

本文已收录于【Spring源码札记专栏】。

关联文章: (一)Spring IoC源码-2.bean的加载-01整体概览 (一)Spring IoC源码-2.bean的加载-02从缓存中获取单例bean (一)Spring IoC源码-2.bean的加载-03从bean实例中获取目标对象 (一)Spring IoC源码-2.bean的加载-04创建bean

创建bean过程概述

创建bean是通过AbstractAutowireCapableBeanFactory.createBean(String, RootBeanDefinition, Object[])完成的。

@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // ??? 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 { //如果配置文件中配置了BeanPostProcessor,则返回一个代理对象。 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; } catch (BeanCreationException ex) { // A previously detected exception with proper bean creation context already... throw ex; } catch (ImplicitlyAppearedSingletonException ex) { // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry... throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }

可以看出,创建bean的功能是委托doCreateBean方法来完成的。在执行doCreateBean方法前,还处理了override属性和做了前置处理。下面看下doCreateBean方法的代码。

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException { BeanWrapper instanceWrapper = null; //如果是单例模式的Bean,先从缓存中获取并删除同名Bean if (mbd.isSingleton()) { instanceWrapper = this.factoryBeanInstanceCache.remove(beanName); } //如果没能从缓存中获取到bean,创建bean实例 if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null); //获取bean的类型 Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null); mbd.resolvedTargetType = beanType; if (beanType != null) { // MergedBeanDefinitionPostProcessor的应用 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; } } } //是否需要提前曝光:是否是单例 & 是否允许循环依赖 & 当前 bean是否正在创建中 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"); } //依赖处理。为了避免循环依赖,可以在 bean 初始化完成前将创建实例的 ObjectFactory加入工厂 addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean)); } Object exposedObject = bean; try { //属性注入。对bean进行填充,将各个属性值注入 populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { //初始化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) { //获取已注册的单态模式Bean对象 Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { //已注册的单态模式Bean对象和正在实例化的Bean是同一个 if (exposedObject == bean) { //当前实例化的Bean初始化完成 exposedObject = earlySingletonReference; } //当发生循环引用时不允许新创建实例对象,并且当前Bean依赖其他Bean else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { //获取当前Bean所依赖的其他Bean String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length); //对依赖Bean进行检查,筛选出正在创建的bean for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } //因为 bean 创建后其所依赖的 bean 一定是已经创建的,actualDependentBeans不为空则表示当前bean创建后其依赖的 bean却没有全部创建完,也就是说存在循环依赖 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."); } } } } if (bean != null) { // Register bean as disposable. try { //注册完成依赖注入的Bean registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } } //完成创建并返回 return exposedObject; }

将步骤总结如下:

清除缓存。如果是bean是单例bean,需要首先清除缓存。创建bean实例。MergedBeanDefinitionPostProcessor的应用。bean合并后的处理,Autowired注解正是通过此方法实现诸如类型的预解析。避免循环依赖。为了避免循环依赖,可以在 bean初始化完成前将创建实例的 ObjectFactory加入工厂。属性注入。将所有属性填充至bean的实例中。初始化bean。循环依赖检查。Sping 中解决循环依赖只对单例有效,而对于prototype的bean,Spring 没有好的解决办法,唯一要做的就是抛出异常。在这个步骤里面会检测已经加载的 bean 是否已经出现了依赖循环,并判断是否需要抛出异常。注册DisposableBean。完成创建并返回。

创建bean实例

createBeanInstance(String, RootBeanDefinition, Object[])负责实例化bean。实例化方式有很多种,比如工厂方法和构造函数,具体使用哪种方式由BeanDefinition指定。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) { // 确认是否可以实例化 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) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same 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); } } // 使用构造函数实例化 Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName); if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) { return autowireConstructor(beanName, mbd, ctors, args); } // 使用默认的构造函数实例化 return instantiateBean(beanName, mbd); }

避免循环依赖

参考(一)Spring IoC源码-2.bean的加载-02从缓存中获取单例bean和(一)IoC源码-3.其他特性的实现原理-02循环依赖的解决。

属性注入

前面已经介绍了如何实例化bean。在此基础上,需要对实例化的bean进行属性注入,即对bean的属性的处理(依赖关系的处理)。populateBean(String, RootBeanDefinition, BeanWrapper)负责这个任务。

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //获取BeanDefinition中的property值 PropertyValues pvs = mbd.getPropertyValues(); if (bw == null) { if (!pvs.isEmpty()) { throw new BeanCreationException( mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance"); } else { // Skip property population phase for null instance. return; } } // 给后置处理器InstantiationAwareBeanPostProcessors最后一次机会在设置属性前改变bean的状态。 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; } //对依赖注入处理,首先处理autowire自动装配的依赖注入 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) { MutablePropertyValues newPvs = new MutablePropertyValues(pvs); //根据Bean名称进行autowire自动装配处理 if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) { autowireByName(beanName, mbd, bw, newPvs); } //根据Bean类型进行autowire自动装配处理 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); if (hasInstAwareBpps || needsDepCheck) { 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); } } //将属性注入到bean中 applyPropertyValues(beanName, mbd, bw, pvs); }

将属性注入步骤总结如下:

给后置处理器InstantiationAwareBeanPostProcessors最后一次机会在设置属性前改变bean的状态。处理autowire自动装配的依赖注入将属性注入到bean中

初始化

在对bean进行实例化、属性注入后,接下来的操作是对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 { //处理特殊的bean invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; //对Bean的后置处理器BeanPostProcessor的postProcessBeforeInitialization方法的调用 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } if (wrappedBean != null) { try { //调用bean的初始化方法,初始化方法通过inti-method属性指定。 //如果bean实现了InitializingBean接口,那么bean的afterPropertiesSet()实现也会被调用。 invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } //对Bean的后置处理器BeanPostProcessor的postProcessAfterInitialization方法的调用 if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } } return wrappedBean; }

将步骤总结如下:

处理特殊的bean(实现了Aware相关接口的bean)。对Bean的后置处理器BeanPostProcessor的postProcessBeforeInitialization方法的调用。调用bean的初始化方法,初始化方法通过inti-method属性指定。如果bean实现了InitializingBean接口,那么bean的afterPropertiesSet()实现也会被调用。对Bean的后置处理器BeanPostProcessor的postProcessAfterInitialization方法的调用。

注册DisposableBean

Spring不但提供了初始化方法的扩展入口,也提供了销毁方法的扩展入口。对于销毁方法的扩展,除了我们熟知的destroy-method属性外,用户开可以注册后处理器DestructionAwareBeanPostProcessor。

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }

bean的生命周期

了解了以上内容后,我们可将bean的生命周期总结如下:

实例化。Spring对Bean进行实例化(默认是单例)属性注入。Spring将值和Bean的引用注入进Bean对应的属性中初始化。 如果Bean实现了BeanNameAware接口,Spring将Bean的ID传递给setBeanName()方法。如果Bean实现了BeanFactoryAware接口,Spring将调用setBeanDactory(BeanFactory bf)方法并把BeanFactory容器实例作为参数传入。如果Bean实现了ApplicationContextAwaer接口,Spring容器将调用setApplicationContext(ApplicationContext ctx)方法,把应用上下文作为参数传入。如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessBeforeInitialization方法。如果Bean实现了InitializingBean接口,Spring将调用它们的afterPropertiesSet方法,作用与在配置文件中对Bean使用init-method声明初始化的作用一样,都是在Bean的全部属性设置成功后执行的初始化方法。如果Bean实现了BeanPostProcess接口,Spring将调用它们的postProcessAfterInitialization方法。注册DispostbleBean。经过以上的工作后,Bean将一直驻留在应用上下文中给应用使用,直到应用上下文被销毁。Bean实例销毁前,如果Bean实现了DispostbleBean接口,Spring将调用它的destory方法。

End。

转载请注明原文地址: https://www.6miu.com/read-2624208.html

最新回复(0)