spring源码:bean加载之准备创建bean(createBean()方法)

一、介绍

  熟悉spring源码的都知道,一般xxx()方法是来做一些准备、辅助之类的工作,真正干活儿的大部分会有一个与之对应的doXxx()方法。createBean()方法也不例外,真正的创建逻辑在doCreateBean()方法中。在真正创建bean之前,会做一些验证、处理的工作。本章就详细介绍一下,创建bean之前具体都执行了哪些步骤。

二、bean加载流程
  1. 获取用户传入name对应的beanName
  2. 尝试从缓存中获取bean实例
  3. 缓存中不存在,加载bean实例
    3.1. 检查循环依赖
    3.2 处理parentBeanFactory
    3.3 处理依赖的bean(dependsOn)
    3.4 三种bean实例的创建
     3.4.1 单例bean的创建
      3.4.1.1 获取单例bean,getSingleton()方法
      3.4.1.2 准备创建bean,createBean()方法(本章解析
      3.4.1.3 创建bean,doCreateBean()方法
     3.4.2 原型bean的创建
     3.4.3 根据scope策略创建bean
  4. 从bean实例中获取真正的对象
  5. 转换对象类型
  6. 返回对象实例
三、相关类及方法
  • org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean:加载一个Bean的整体过程都在这个方法中
  • org.springframework.beans.factory.support.AbstractBeanDefinition#prepareMethodOverrides:验证methodOverrides
  • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:执行BeanPostProcessor后处理器
四、源码分析

1. 先看加载bean的方法,AbstractBeanFactory#doGetBean

	protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
				@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
		// 1.转换beanName,主要处理别名、以&开头的name
		final String beanName = transformedBeanName(name);
		Object bean;
	
		// 2.尝试从单例缓存中获取bean实例
		Object sharedInstance = getSingleton(beanName);
		// 3. 获取bean实例
		// 3.1 缓存中已存在bean实例
		if (sharedInstance != null && args == null) {
			// 省略日志输出代码...
			// 从bean实例中获取对象(本章重点,获取实例中的对象)
			bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
		}
		// 缓存中不存在bean实例的情况
		else {
			// 省略父工厂处理相关代码...
			try {
				// 省略dependsOn相关代码...

				// 3.2 创建单例bean
				if (mbd.isSingleton()) {
					// 获取单例(本章重点)
					sharedInstance = getSingleton(beanName, () -> {
						try {
							return createBean(beanName, mbd, args);
						}
						catch (BeansException ex) {
							destroySingleton(beanName);
							throw ex;
						}
					});
					bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
				}
				// 3.3 创建原型bean实例
				else if (mbd.isPrototype()) {
				// 省略原型bean创建逻辑...
				}
				// 3.4 根据scope创建bean实例
				else {
					// 省略根据scope策略创建bean逻辑...
				}
			}
			catch (BeansException ex) {
				cleanupAfterBeanCreationFailure(beanName);
				throw ex;
			}
		}
		// 省略其他代码.
		...
	}

可以看到缓存中不存在bean实例时,创建单例bean的逻辑是调用getSingleton()方法完成的,跟进去看下具体逻辑。

2. 准备创建bean

	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;

		// 1. 解析bean对应的Class
		Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
		if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
			mbdToUse = new RootBeanDefinition(mbd);
			mbdToUse.setBeanClass(resolvedClass);
		}
		
		try {
			// 2. 验证methodOverride对应的方法是否存在?是否有重载?(重点方法)
			mbdToUse.prepareMethodOverrides();
		}
		catch (BeanDefinitionValidationException ex) {
			throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
					beanName, "Validation of method overrides failed", ex);
		}

		try {
			// 3. 给BeanPostProcessor一个机会来返回代理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 {
			// 4. 创建bean
			Object beanInstance = doCreateBean(beanName, mbdToUse, args);
			if (logger.isDebugEnabled()) {
				logger.debug("Finished creating instance of bean '" + beanName + "'");
			}
			return beanInstance;
		}
		catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
			throw ex;
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
		}
	}

可以看到以上有4个步骤:

  1. 解析beanName对应的Class
  2. 验证methodOverride对应的方法是否存在?是否有重载?
    其中methodOverride指的是bean标签的lookup-methodreplaced-method 两个字标签。详见《bean标签的解析之简单子元素的解析》
  3. 给BeanPostProcessor一个机会返回bean
  4. 创建bean:doCreateBean()

下面分别看下2和3两个步骤的代码

3. 验证methodOverride

	public void prepareMethodOverrides() throws BeanDefinitionValidationException {
		// Check that lookup methods exists.
		if (hasMethodOverrides()) {
			// 获取该beanDefinition中的overrides
			Set<MethodOverride> overrides = getMethodOverrides().getOverrides();
			synchronized (overrides) {
				for (MethodOverride mo : overrides) {
					// 循环处理
					prepareMethodOverride(mo);
				}
			}
		}
	}

	protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException {
		// class中该方法名的个数
		int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName());
		if (count == 0) {
			// 没有该方法,则抛出异常
			throw new BeanDefinitionValidationException(
					"Invalid method override: no method with name '" + mo.getMethodName() +
					"' on class [" + getBeanClassName() + "]");
		}
		else if (count == 1) {
			// 如果该方法名只有一个方法,则证明该方法没有重载,记录在此
			mo.setOverloaded(false);
		}
	}

此步骤主要目的是,验证AbstractBeanDefinition#methodOverrides中的methodName对应的方法情况。校验该bean对应的Class对象是否存在methodName方法,该方法是否有重载。这一切都是为了后面实例化bean做准备。

4. 执行BeanPostProcessor尝试返回bean

	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		// 如果beanDefinition未被解析
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// 不是自定义的beanDefinition
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 实例化前的后处理器应用
					// 如果此处返回bean不为空,则实例化后的beanProcessor继续处理
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						// 实例化后的后处理器应用
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			// InstantiationAwareBeanPostProcessor类型的beanProcessor才有资格处理
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				// 实例化之前的后处理
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		Object result = existingBean;
		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
			// 实例化之后的后处理
			// 拿到实例化前的beanProcessor处理结果,交由实例化后的beanProcessor继续处理
			Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
				return result;
			}
			result = current;
		}
		return result;
	}

可以看到doCreateBean()方法之前,可以通过容器中InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation()方法返回bean;在Before有返回的前提下,也可以通过容器中BeanPostProcessor#postProcessAfterInitialization()方法继续处理返回bean。最终的返回结果,决定程序是否执行doCreateBean()方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值