【Spring源码】createBean()

【Spring源码】createBean(),第1张

【Spring源码】createBean()

目录
    • 1、resolveBeanClass()
    • 2、prepareMethodOverrides()
    • 3、resolveBeforeInstantiation()
      • 1)applyBeanPostProcessorsBeforeInstantiation()
      • 2)applyBeanPostProcessorsAfterInitialization()

    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

@Nullable
protected Class resolveBeanClass(RootBeanDefinition mbd, String beanName, Class... typesToMatch) {
	if (mbd.hasBeanClass()) {
		return mbd.getBeanClass();
	}
	if (System.getSecurityManager() != null) {
		return AccessController.doPrivileged((PrivilegedExceptionAction>)
				() -> 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()

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

	
	public void prepareMethodOverrides(){
		// Check that lookup methods exist and determine their overloaded status.
		if (hasMethodOverrides()) {
			// MethodOverrides methodOverrides = new MethodOverrides();
			// final Set overrides = new CopyOnWriteArraySet<>();
			getMethodOverrides().getOverrides().forEach(this::prepareMethodOverride);
		}
	}

	
	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()。

	
	@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 生成的,也可能是通过其他技术生成的。

	
	@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;
	}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/zaji/5694643.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-12-17
下一篇2022-12-17

发表评论

登录后才能评论

评论列表(0条)

    保存