【Spring源码】createBean()

    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and 确保此时真正解析了 bean 类,并且
        // clone the bean definition in case of a dynamically resolved Class 在动态解析类的情况下克隆 bean 定义
        // which cannot be stored in the shared merged bean definition. 不能存储在共享的合并 bean 定义中
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // 2、验证及准备覆盖的方法
        // Prepare method overrides.
        mbdToUse.prepareMethodOverrides();

        // 3、应用初始化前的后处理器,解析指定bean是否存在初始化前的短路操作
        // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        // AOP功能基于这里的判断,经过前置处理后返回的结果如果不为空,直接返回结果
        if (bean != null) {
            return bean;
        }
		// Central method of this class: creates a bean instance,  populates the bean instance, applies post-processors, etc.
		// 这个类的中心方法:创建一个bean实例,填充 bean 实例,应用后处理器等
        return doCreateBean(beanName, mbdToUse, args);
    }

1、resolveBeanClass()

锁定class,根据设置的class属性或者根据className 来解析 Class

/**
 * Resolve the bean class for the specified bean definition, 解析指定bean定义的bean类,
 * resolving a bean class name into a Class reference (if necessary) 将 bean 类名解析为类引用(如有必要)
 * and storing the resolved Class in the bean definition for further use. 并将解析后的 Class 存储在 bean 定义中以供进一步使用。
 * @param mbd the merged bean definition to determine the class for. 合并 bean 定义以确定类
 * @param beanName the name of the bean (for error handling purposes). bean 的名称(用于错误处理目的)
 * @param typesToMatch the types to match in case of internal type matching purposes. 在内部类型匹配的情况下要匹配的类型
 * (also signals that the returned {@code Class} will never be exposed to application code) (也表明返回的 {@code Class} 永远不会暴露给应用程序代码)
 * @return the resolved bean class (or {@code null} if none) 已解析的 bean 类(如果没有,则为 {@code null})
 * @throws CannotLoadBeanClassException if we failed to load the class 如果我们加载类失败
 */
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch) {
	if (mbd.hasBeanClass()) {
		return mbd.getBeanClass();
	}
	if (System.getSecurityManager() != null) {
		return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
				() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
	} else {
		return doResolveBeanClass(mbd, typesToMatch);
	}
}

@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch) {
	ClassLoader beanClassLoader = getBeanClassLoader();
	ClassLoader classLoaderToUse = beanClassLoader;
	if (!ObjectUtils.isEmpty(typesToMatch)) {
		// When just doing type checks (i.e. not creating an actual instance yet),
		// use the specified temporary class loader (e.g. in a weaving scenario).
		ClassLoader tempClassLoader = getTempClassLoader();
		if (tempClassLoader != null) {
			classLoaderToUse = tempClassLoader;
			if (tempClassLoader instanceof DecoratingClassLoader) {
				DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
				for (Class<?> typeToMatch : typesToMatch) {
					dcl.excludeClass(typeToMatch.getName());
				}
			}
		}
	}
	String className = mbd.getBeanClassName();
	if (className != null) {
		Object evaluated = evaluateBeanDefinitionString(className, mbd);
		if (!className.equals(evaluated)) {
			// A dynamically resolved expression, supported as of 4.2...
			if (evaluated instanceof Class) {
				return (Class<?>) evaluated;
			} else if (evaluated instanceof String) {
				return ClassUtils.forName((String) evaluated, classLoaderToUse);
			}
		}
		// When resolving against a temporary class loader, exit early in order
		// to avoid storing the resolved Class in the bean definition.
		if (classLoaderToUse != beanClassLoader) {
			return ClassUtils.forName(className, classLoaderToUse);
		}
	}
	return mbd.resolveBeanClass(beanClassLoader);
}

2、prepareMethodOverrides()

对Override属性标记及验证
在 Spring 配置中存在 lookup - method 和 replace - method 两个配置功能,而这两个配置的加载其实就是将配置统一存放在 BeanDefinition 中的 methodOverrides 属性里,这两个功能实现原理其实是在 bean 实例化的时候如果检测到存在 methodOverrides 属性,会动态地为当前 bean 生成代理并使用对应的拦截器为 bean 做增强处理。
对于方法的匹配来讲,如果一个类中存在若干个重载方法,那么,在函数调用及增强的时候还需要根据参数类型进行匹配,来最终确认当前调用的到底是哪个函数。但是, Spring 将一部分匹配工作在这里完成了,如果当前类中的方法只有一个,那么就设置重载该方法没有被重载,这样在后续调用的时候便可以直接使用找到的方法,而不需要进行方法的参数匹配验证了,而且还可以提前对方法存在性进行验证。

	/**
	 * Validate and prepare the method overrides defined for this bean. 验证并准备为此 bean 定义的方法覆盖。
	 * Checks for existence of a method with the specified name. 检查具有指定名称的方法是否存在。
	 * @throws BeanDefinitionValidationException in case of validation failure
	 */
	public void prepareMethodOverrides(){
		// Check that lookup methods exist and determine their overloaded status.
		if (hasMethodOverrides()) {
			// MethodOverrides methodOverrides = new MethodOverrides();
			// final Set<MethodOverride> overrides = new CopyOnWriteArraySet<>();
			getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
		}
	}

	/**
	 * Validate and prepare the given method override.
	 * Checks for existence of a method with the specified name,
	 * marking it as not overloaded if none found.
	 * @param mo the MethodOverride object to validate
	 * @throws BeanDefinitionValidationException in case of validation failure
	 */
	protected void prepareMethodOverride(MethodOverride mo) {
		// 获取对应方法名的个数
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		if (count == 1) {
			// 标记 MethodOverrides 为未覆盖,避免参数类型检查的开销
			// Mark override as not overloaded, to avoid the overhead of arg type checking.
			mo.setOverloaded(false);
		}
	}	

3、resolveBeforeInstantiation()

实例化的前置处理
对后处理器中的所有 InstantiationAwareBeanPostProcessor 类型的后处理器 调用 postProcessBeforelnstantiation() 和 BeanPostProcessor 的 postProcessAfterInitialization()。

	/**
	 * Apply before-instantiation post-processors, resolving whether there is a
	 * before-instantiation shortcut for the specified bean.
	 * @param beanName the name of the bean
	 * @param mbd the bean definition for the bean
	 * @return the shortcut-determined bean instance, or {@code null} if none
	 */
	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		// 如果尚未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}	

1)applyBeanPostProcessorsBeforeInstantiation()

在 bean 的实例化前会调用后处理器的方法进行处理
bean 的实例化前调用,也就是将 AbsractBeanDefinition 转换为 BeanWrapper 前的处理。
给子类一个修改 BeanDefinition 的机会,也就是说当程序经过这个方法后, bean 可能已经不是我们认为的 bean 了,而是或许成为了一个经过处理的代理 bean ,可能是通过 cglib 生成的,也可能是通过其他技术生成的。

	/**
	 * Apply InstantiationAwareBeanPostProcessors to the specified bean definition
	 * (by class and name), invoking their {@code postProcessBeforeInstantiation} methods.
	 * <p>Any returned object will be used as the bean instead of actually instantiating
	 * the target bean. A {@code null} return value from the post-processor will
	 * result in the target bean being instantiated.
	 * @param beanClass the class of the bean to be instantiated
	 * @param beanName the name of the bean
	 * @return the bean object to use instead of a default instance of the target bean, or {@code null}
	 * @see InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation
	 */
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

2)applyBeanPostProcessorsAfterInitialization()

实例化后的后处理器应用
Spring 中的规则是在 bean 的初始化后尽可能保证将注册的后处理器的 postProcessAfterlnitialization() 应用到该 bean 中,因为如果返回的 bean 不为空,那么便不会再次经历普通 bean 的创建过程,所以只能在这里应用后处理器的 postProcessAfterInitialization()。

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值