Spring 5 AbstractAutowireCapableBeanFactory-- createBeanInstance 源码解析

相关源码注释

ApplicationContext

Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释

BeanFactory

Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释

createBeanInstance(beanName, mbd, args);

使用适当的实例化策略为指定的Bean创建一个新实例:工厂方法,构造函数自动装配或简单实例化。

  1. 使用工厂方法(多个工厂方法时,会找到最匹配的那个构造函数),优先使用 args的参数值来实例化对象, 没有就使用mdb所定义的参数值
  2. 使用构造函数:
    1. 从SmartInstantiationAwareBeanPostProcessor中获取给定bean的候选构造函数 || mdb的解析自动注入模式为 按构造器自动装配 || mbd有构造函数参数 || args不为null,会以自动注入 方式调用最匹配的构造函数来实例化参数对象并返回出去
    2. 从mbd中获取首选的构造函数,以自动注入方式调用最匹配的构造函数来实例化参数对象并返回出去
    3. 无须特殊处理,只需使用无参数的构造函数
/**
	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
	 * factory method, constructor autowiring, or simple instantiation.
	 * <p>使用适当的实例化策略为指定的Bean创建一个新实例:工厂方法,构造函数自动装配或简单实例化。</p>
	 * @param beanName the name of the bean -- bean名
	 * @param mbd the bean definition for the bean -- bean的BeanDefinition
	 * @param args explicit arguments to use for constructor or factory method invocation
	 *             -- 用于构造函数或工厂方法调用的显示参数
	 * @return a BeanWrapper for the new instance -- 新实例的BeanWrapper
	 * @see #obtainFromSupplier
	 * @see #instantiateUsingFactoryMethod
	 * @see #autowireConstructor
	 * @see #instantiateBean
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    
    
		// Make sure bean class is actually resolved at this point.
		// 确保此时确实解决了bean类
		//获取mdb解析出对应的bean class
		Class<?> beanClass = resolveBeanClass(mbd, beanName);
		//如果成功获取到beanClass且beanClass不是用public且mbd不允许访问非公共构造函数和方法
		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
    
    
			//抛出Bean创建异常:bean类不是公共的,并且不允许非公共访问
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		//获取创建bean定义的回调对象
		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		//如果有回调对象
		if (instanceSupplier != null) {
    
    
			//从instanceSupplier那里获取一个bean实例,并对其包装成BeanWrapper对象:
			return obtainFromSupplier(instanceSupplier, beanName);
		}
		//如果mbd有配置工厂方法名
		if (mbd.getFactoryMethodName() != null) {
    
    
			//使用命名工厂方法实例化beanName所对应的bean对象
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		//没有工厂方法的情况
		// Shortcut when re-creating the same bean...
		// 重新创建相同Bena的快捷方式
		//是否已解析出构造函数标记,默认为false,表示还没有解析
		boolean resolved = false;
		//必须要自动注入标记,默认为false,表示不需要
		boolean autowireNecessary = false;
		//如果args为null
		if (args == null) {
    
    
			//使用mbd的构造函数通用锁【{@link RootBeanDefinition#constructorArgumentLock}】加锁以保证线程安全:
			synchronized (mbd.constructorArgumentLock) {
    
    
				//如果mdb的已解析的构造函数或工厂方法【{@link RootBeanDefinition#resolvedConstructorOrFactoryMethod}】不为null
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
    
    
					//设置resloved为true,表示已解析
					resolved = true;
					//让autowireNecessary引用mbd的构造函数参数已解析标记值【{@link RootBeanDefinition#constructorArgumentsResolved}】,
					// 如果构造函数参数已解析,表示必须要自动注入;否则不需要自动注入
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		//如果已解析出构造函数
		if (resolved) {
    
    
			//如果必须要自动注入
			if (autowireNecessary) {
    
    
				//以自动注入方式调用最匹配的构造函数来实例化参数对象并返回出去
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
    
    
				//使用其默认构造函数实例化给定的Bean并返回出去
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		// 自动装配的候选构造函数?
		//从SmartInstantiationAwareBeanPostProcessor中获取给定bean的候选构造函数
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		//如果ctors不为null || mdb的解析自动注入模式为 按构造器自动装配 || mbd有构造函数参数 || args不为null
		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();
		//ctor不为null
		if (ctors != null) {
    
    
			//以自动注入方式调用最匹配的构造函数来实例化参数对象并返回出去
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 无须特殊处理,只需使用无参数的构造函数
		return instantiateBean(beanName, mbd);
	}

resolveBeanClass(mbd, beanName);

Spring 5 AbstractBeanFactory – resolveBeanClass源码解析

obtainFromSupplier(instanceSupplier, beanName);

从给定的供应商那里获取一个bean实例,并对其包装成BeanWrapper对象:

  1. 声明一个实例对象【变量 instance】
  2. 从线程本地当前创建的bean名称【currentlyCreatedBean】中获取原先创建bean的名字【变量 outerBean】
  3. 保存beanName到currentlyCreatedBean中
  4. 从配置的Supplier中获取一个bean实例,赋值instance
  5. 【finally】如果原先bean存在,将保存到currentlyCreatedBean中;否则就将beanName移除
  6. 如果没有成功获取到instance,instance就引用NullBean
  7. 对instance包装成BeanWrapper对象【变量 bw】
  8. 初始化bw 【initBeanWrapper(BeanWrapper)】
  9. 返回初始化后的bw
/**
	 * The name of the currently created bean, for implicit dependency registration
	 * on getBean etc invocations triggered from a user-specified Supplier callback.
	 * <p>当前创建的bean名称,用于从用户指定的Supplier回调触发的对getBean等调用的隐式依赖项注册</p>
	 */
	private final NamedThreadLocal<String> currentlyCreatedBean = new NamedThreadLocal<>("Currently created bean");

/**
	 * Obtain a bean instance from the given supplier.
	 * <p>从给定的供应商那里获取一个bean实例</p>
	 * @param instanceSupplier the configured supplier -- 配置的供应商
	 * @param beanName the corresponding bean name -- 对应的bean名
	 * @return a BeanWrapper for the new instance -- 新实例的BeanWrapper
	 * @since 5.0
	 * @see #getObjectForBeanInstance
	 */
	protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {
    
    
		//实例对象
		Object instance;
		//从线程本地当前创建的bean名称【currentlyCreatedBean】中获取原先创建bean的名字
		String outerBean = this.currentlyCreatedBean.get();
		//保存新的bean的名字到currentlyCreatedBean中
		this.currentlyCreatedBean.set(beanName);
		try {
    
    
			//从配置的Supplier中获取一个bean实例
			instance = instanceSupplier.get();
		}
		finally {
    
    
			//如果原先bean存在,将保存到currentlyCreatedBean中
			if (outerBean != null) {
    
    
				this.currentlyCreatedBean.set(outerBean);
			}
			else {
    
    
				//如果没有就将beanName移除
				this.currentlyCreatedBean.remove();
			}
		}
		// BeanWrapperImpl类是对BeanWrapper接口的默认实现,它包装了一个bean对象,
		// 缓存了bean的内省结果, 并可以访问bean的属性、设置bean的属性值。BeanWrapperImpl
		// 类提供了许多默认属性编辑器, 支持多种不同类型的类型转换,可以将数组、集合类型的属
		// 性转换成指定特殊类型的数组或集合。 用户也可以注册自定义的属性编辑器在BeanWrapperImpl中。
		//如果没有成功获取到bean实例
		if (instance == null) {
    
    
			//bean实例就引用NullBean
			instance = new NullBean();
		}
		//对instance进行包装
		BeanWrapper bw = new BeanWrapperImpl(instance);
		//初始化包装对象
		initBeanWrapper(bw);
		//返回初始化后的bw
		return bw;
	}

initBeanWrapper(bw);

初始化BeanWrapper:

  1. 使用该工厂的ConversionService来作为bw的ConverisonService,用于转换属性值,以替换JavaBeans PropertyEditor
  2. 将PropertyEditor注册到bw中
/**
	 * Initialize the given BeanWrapper with the custom editors registered
	 * with this factory. To be called for BeanWrappers that will create
	 * and populate bean instances.
	 * <p>使用在此工厂注册的自定义编辑器初始化给定的BeanWrapper。被BeanWrappers调用,
	 * 它将创建并填充Bean实例</p>
	 * <p>The default implementation delegates to {@link #registerCustomEditors}.
	 * Can be overridden in subclasses.
	 * <p>默认实现委派registerCustomEditor。可以在子类中覆盖</p>
	 * @param bw the BeanWrapper to initialize -- 要初始化的BeanWrapper
	 */
	protected void initBeanWrapper(BeanWrapper bw) {
    
    
		//使用该工厂的ConversionService来作为bw的ConverisonService,用于转换属性值,以替换JavaBeans PropertyEditor
		bw.setConversionService(getConversionService());
		//将工厂中所有PropertyEditor注册到bw中
		registerCustomEditors(bw);
	}

registerCustomEditors(bw);

将工厂中所有PropertyEditor注册到PropertyEditorRegistry中:

  1. 将registry强转成PropertyEditorRegistrySupport对象,如果registry不能强转则为null【变量registrySupport】
  2. 如果成功获取registrySupport,就激活仅用于配置目的的配置值编辑器,例如:StringArrayPropertyEditor.
  3. 如果该工厂的propertyEditorRegistry列表【propertyEditorRegistrars】不为空
    1. 遍历propertyEditorRegistrars,元素为registrar:
      1. 将registrar中的所有PropertyEditor注册到PropertyEditorRegistry中
      2. 捕捉Bean创建异常【变量ex】:
        1. 获取ex中最具体的原因【变量 rootCause】
        2. 如果是因为当前正在创建Bean异常:
          1. 将rootCause强转成BeanCreationException【变量 bce】
          2. 获取发生异常的bean名【变量 bceBeanName】
          3. 如果bean名不为null 且 是该bean名正在被创建:
            1. 如果是日志级别是调试级别,打印调试日志
            2. 将要注册的异常对象添加到 抑制异常列表【suppressedExceptions】 中
            3. 不再抛出异常,继续循环
          4. 重写抛出ex
    2. 如果该工厂的自定义PropertyEditor集合【customEditors】有元素:遍历customEditors,将其注册到registry中
/**
	 * Custom PropertyEditorRegistrars to apply to the beans of this factory.
	 * <p>定制PropertyEditorRegistrars应用于此工厂的bean。</p>
	 * */
	private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);

/**
	 * Initialize the given PropertyEditorRegistry with the custom editors
	 * that have been registered with this BeanFactory.
	 * <p>使用已在此BeanFactory中注册的自定义编辑器初始化给定的PropertyEditorRegistry</p>
	 * <p>To be called for BeanWrappers that will create and populate bean
	 * instances, and for SimpleTypeConverter used for constructor argument
	 * and factory method type conversion.
	 * <p>对于将创建和填充bean实例的BeanWrappers以及用于构造函数参数和工厂方法类型转换
	 * 的SimpleTypeConverter调用</p>
	 * @param registry the PropertyEditorRegistry to initialize -- 要进行初始化的PropertyEditorRegistry
	 */
	protected void registerCustomEditors(PropertyEditorRegistry registry) {
    
    
		//PropertyEditorRegistrySupport是PropertyEditorRegistry接口的默认实现
		//将registry强转成PropertyEditorRegistrySupport对象,如果registry不能强转则为null
		PropertyEditorRegistrySupport registrySupport =
				(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
		//如果成功获取PropertyEditorRegistrySupport对象
		if (registrySupport != null) {
    
    
			//激活仅用于配置目的的配置值编辑器,例如:StringArrayPropertyEditor.
			registrySupport.useConfigValueEditors();
		}
		//PropertyEditorRegistrar:各种业务的PropertyEditorSupport一般都会先注册到PropertyEditorRegistrar中,再通过PropertyEditorRegistrar
		//将PropertyEditorSupport注册到PropertyEditorRegistry中
		//如果该工厂的propertyEditorRegistrar列表不为空
		if (!this.propertyEditorRegistrars.isEmpty()) {
    
    
			//propertyEditorRegistrars默认情况下只有一个元素对象,该对象为ResourceEditorRegistrar。
			//遍历propertyEditorRegistrars
			for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
    
    
				try {
    
    
					//ResourceEditorRegitrar会将ResourceEditor, InputStreamEditor, InputSourceEditor,
					// 	FileEditor, URLEditor, URIEditor, ClassEditor, ClassArrayEditor注册到registry中,
					// 如果registry已配置了ResourcePatternResolver,则还将注册ResourceArrayPropertyEditor
					//将registrar中的所有PropertyEditor注册到PropertyEditorRegistry中
					registrar.registerCustomEditors(registry);
				}
				//捕捉Bean创建异常
				catch (BeanCreationException ex) {
    
    
					//获取ex中最具体的原因
					Throwable rootCause = ex.getMostSpecificCause();
					//如果是因为当前正在创建Bean异常
					if (rootCause instanceof BeanCurrentlyInCreationException) {
    
    
						//将rootCause强转成BeanCreationException
						BeanCreationException bce = (BeanCreationException) rootCause;
						//获取发生异常的bean名
						String bceBeanName = bce.getBeanName();
						//如果bean名不为null 且 是该bean名正在被创建
						if (bceBeanName != null && isCurrentlyInCreation(bceBeanName)) {
    
    
							//如果是日志级别是调试级别
							if (logger.isDebugEnabled()) {
    
    
								//打印调试日志:PropertyEditorRegistrar[registrar全类名]失败因为它试图获取
								// 当前创建的bean'发生异常的bean名':异常信息
								logger.debug("PropertyEditorRegistrar [" + registrar.getClass().getName() +
										"] failed because it tried to obtain currently created bean '" +
										ex.getBeanName() + "': " + ex.getMessage());
							}
							//将要注册的异常对象添加到 抑制异常列表 中,注意抑制异常列表【#suppressedExceptions】是Set集合
							onSuppressedException(ex);
							//不再抛出异常
							continue;
						}
					}
					//重写抛出ex
					throw ex;
				}
			}
		}
		//如果该工厂的自定义PropertyEditor集合有元素,在SpringBoot中,customEditors默认是空的
		if (!this.customEditors.isEmpty()) {
    
    
			//遍历自定义PropertyEditor集合,将其元素注册到registry中
			this.customEditors.forEach((requiredType, editorClass) ->
					registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
		}
	}

instantiateUsingFactoryMethod(beanName, mbd, args);

使用工厂方法实例化对象

/**
	 * Instantiate the bean using a named factory method. The method may be static, if the
	 * mbd parameter specifies a class, rather than a factoryBean, or an instance variable
	 * on a factory object itself configured using Dependency Injection.
	 * <p>使用命名工厂方法实例化bean。如果mbd参数指定一个类(而不是factoryBean)或使用依赖注入配置
	 * 的工厂对象本身的实例变量,则该方法可以是静态的。</p>
	 * @param beanName the name of the bean -- bean名
	 * @param mbd the bean definition for the bean -- bean的BeanDefinition
	 * @param explicitArgs argument values passed in programmatically via the getBean method,
	 * or {@code null} if none (-> use constructor argument values from bean definition)
	 * -- 通过getBean方法以编程方式传递的参数值;如果没有,则返回null(->使用bean定义的构造函数参数值)
	 * @return a BeanWrapper for the new instance -- 新实例的BeanWrapper
	 * @see #getBean(String, Object[])
	 */
	protected BeanWrapper instantiateUsingFactoryMethod(
			String beanName, RootBeanDefinition mbd, @Nullable Object[] explicitArgs) {
    
    
		//实例化一个新的ConstructorResolver对象,让其使用工厂方法实例化beanName所对应的Bean对象:
		return new ConstructorResolver(this).instantiateUsingFactoryMethod(beanName, mbd, explicitArgs);
	}

Spring 5 ConstructorResolver 源码注释

autowireConstructor(beanName, mbd, null, null);

以自动注入方式调用最匹配的构造函数来实例化参数对象

/**
	 * "autowire constructor" (with constructor arguments by type) behavior.
	 * Also applied if explicit constructor argument values are specified,
	 * matching all remaining arguments with beans from the bean factory.
	 * <p>"autowire constructor"(按类型带有构造函数参数)的行为。如果显示指定了构造函数自变量值,
	 * 则将所有剩余自变量与Bean工厂中的Bean进行匹配时也适用</p>
	 * <p>This corresponds to constructor injection: In this mode, a Spring
	 * bean factory is able to host components that expect constructor-based
	 * dependency resolution.
	 * <p>这对应于构造函数注入:在这种模式下,Spring Bean工厂能够托管需要基于构造函数数的
	 * 依赖关系解析的组件</p>
	 * @param beanName the name of the bean -- Bean名
	 * @param mbd the bean definition for the bean -- Bean的BeanDefinition
	 * @param ctors the chosen candidate constructors -- 选择的候选构造函数
	 * @param explicitArgs argument values passed in programmatically via the getBean method,
	 * or {@code null} if none (-> use constructor argument values from bean definition)
	 *                     -- 用于构造函数或工厂方法调用的显示参数
	 * @return a BeanWrapper for the new instance -- 新实例的BeanWrapper
	 */
	protected BeanWrapper autowireConstructor(
			String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {
    
    
		//实例化一个新的ConstructorResolver对象,以自动注入方式调用最匹配的构造函数来实例化参数对象
		return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
	}

instantiateBean(beanName, mbd);

使用其默认构造函数实例化给定的Bean

扫描二维码关注公众号,回复: 12430959 查看本文章
/**
	 * Instantiate the given bean using its default constructor.
	 * <p>使用其默认构造函数实例化给定的Bean</p>
	 * @param beanName the name of the bean -- bean名
	 * @param mbd the bean definition for the bean -- bean的beanDefinition
	 * @return a BeanWrapper for the new instance -- 新实例的BeanWrapper实例
	 */
	protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    
    
		try {
    
    
			Object beanInstance;
			final BeanFactory parent = this;
			//如果安全管理器,就使用特权方式 获取实例化策略对象进行实例化对象
			if (System.getSecurityManager() != null) {
    
    
				beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
						getInstantiationStrategy().instantiate(mbd, beanName, parent),
						getAccessControlContext());
			}
			else {
    
    
				//否则,直接获取实例化策略对象进行实例化对象
				beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
			}
			//包装bean对象
			BeanWrapper bw = new BeanWrapperImpl(beanInstance);
			//初始化 bw
			initBeanWrapper(bw);
			return bw;
		}
		catch (Throwable ex) {
    
    
			//捕捉所有实例化对象时抛出的异常,重新抛出创建BeanCreateException异常
			throw new BeanCreationException(
					mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
		}
	}

determineConstructorsFromBeanPostProcessors(beanClass, beanName);

从 SmartInstantiationAwareBeanPostProcessor 中获取给定bean的候选构造函数

/**
	 * Determine candidate constructors to use for the given bean, checking all registered
	 * {@link SmartInstantiationAwareBeanPostProcessor SmartInstantiationAwareBeanPostProcessors}.
	 * <p>确定为给定的bean使用的候选构造函数,检查所有已注册的 SmartInstantiationAwareBeanPostProcessors</p>
	 * @param beanClass the raw class of the bean -- bean的原始类
	 * @param beanName the name of the bean -- bean名
	 * @return the candidate constructors, or {@code null} if none specified -- 候选构造函数,或 null (如果没有指定)
	 * @throws org.springframework.beans.BeansException in case of errors -- 以防出现错误
	 * @see org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor#determineCandidateConstructors
	 */
	@Nullable
	protected Constructor<?>[] determineConstructorsFromBeanPostProcessors(@Nullable Class<?> beanClass, String beanName)
			throws BeansException {
    
    
		//如果 beanClas 不为null 且 此工厂拥有InstiationAwareBeanPostProcessor
		if (beanClass != null && hasInstantiationAwareBeanPostProcessors()) {
    
    
			//遍历BeanPostProcessor
			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    
    
				//如果 bp 是 SmartInstantiationAwareBeanPostProcessor 实例
				if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
    
    
					SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
					//从ibp中获取指定的候选构造函数
					Constructor<?>[] ctors = ibp.determineCandidateConstructors(beanClass, beanName);
					if (ctors != null) {
    
    
						return ctors;
					}
				}
			}
		}
		return null;
	}

猜你喜欢

转载自blog.csdn.net/qq_30321211/article/details/108350140