5、Spring之Bean生命周期~创建Bean(1)

创建Bean

  Spring Bean的生命周期首先会经过扫描,然后回经过合并,合并之后就会通过getBean()方法去获取bean,getBean()方法大致逻辑,先根据判断是单例bean还是原型bean,原型bean直接创建,单例bean会判断单例池中有没有,没有的话调用createBean()方法。而createBean方法也没有真正的执行实例化操作,而是执行啦实例化前操作,废话不多说,直接上代码:

//---------------------------------------------------------------------
// Implementation of relevant AbstractBeanFactory template methods
//---------------------------------------------------------------------

/**
 * Central method of this class: creates a bean instance,
 * populates the bean instance, applies post-processors, etc.
 *
 * @see #doCreateBean
 */
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
		throws BeanCreationException {

	if (logger.isTraceEnabled()) {
		logger.trace("Creating instance of bean '" + beanName + "'");
	}
	RootBeanDefinition mbdToUse = mbd;

	// Make sure bean class is actually resolved at this point, and
	// clone the bean definition in case of a dynamically resolved Class
	// which cannot be stored in the shared merged bean definition.
	// 马上就要实例化Bean了,确保beanClass被加载了
	Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
	if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
		mbdToUse = new RootBeanDefinition(mbd);
		mbdToUse.setBeanClass(resolvedClass);
	}

	// Prepare method overrides.
	try {
		mbdToUse.prepareMethodOverrides();
	} catch (BeanDefinitionValidationException ex) {
		throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
				beanName, "Validation of method overrides failed", ex);
	}

	try {
		// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
		// 实例化前
		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 {
		Object beanInstance = doCreateBean(beanName, mbdToUse, args);
		if (logger.isTraceEnabled()) {
			logger.trace("Finished creating instance of bean '" + beanName + "'");
		}
		return beanInstance;
	} catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
		// A previously detected exception with proper bean creation context already,
		// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
		throw ex;
	} catch (Throwable ex) {
		throw new BeanCreationException(
				mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
	}
}

通过上述代码,我们就可以看到createBean()方法并不是直接去创建Bean对象,而是要经过一系列的准备工作,我们开始逐行分析:

  1. 首先会调用resolveBeanClass()方法,确保Bean对象的class已经被加载;
  2. prepareMethodOverrides()方法的作用是判断MethodOverrides属性是否存在,存在的话进行方法覆盖,由于配置文件方式使用较少,此方法不展示细说,感兴趣的小伙伴可以自行查阅相关资料;
  3. 再往下就到啦比较重要的实例化前,调用resolveBeforeInstantiation()方法,执行初始化前操作;
  4. 如果实例化前这一步有返回值,会直接返回,不走后续的实例化、依赖注入、初始化前,直接跳到初始化这一步,执行AOP操作;
  5. 调用doCreateBean()方法执行;由于doCreateBean()方法逻辑比较多,请移步至《Spring之Bean生命周期~创建Bean(2)

resolveBeanClass()方法

resolveBeanClass()方法详解

/**
 * Resolve the bean class for the specified bean definition,
 * resolving a bean class name into a Class reference (if necessary)
 * and storing the resolved Class in the bean definition for further use.
 *
 * @param mbd          the merged bean definition to determine the class for
 * @param beanName     the name of the bean (for error handling purposes)
 * @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)
 * @return the resolved bean class (or {@code null} if none)
 * @throws CannotLoadBeanClassException if we failed to load the class
 */
@Nullable
protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
		throws CannotLoadBeanClassException {

	try {
		// 如果beanClass被加载了
		if (mbd.hasBeanClass()) {
			return mbd.getBeanClass();
		}

		// 如果beanClass没有被加载
		if (System.getSecurityManager() != null) {
			return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
					() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
		} else {
			return doResolveBeanClass(mbd, typesToMatch);
		}
	} catch (PrivilegedActionException pae) {
		ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
	} catch (ClassNotFoundException ex) {
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
	} catch (LinkageError err) {
		throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
	}
}

通过上述代码我们可以看到:

  1. 如果beanClass被加载过,直接返回;
  2. 如果还没有被加载,调用doResolveBeanClass()方法加载beanClass,并且拿到类加载器;
  3. 返回createBean()方法;

doResolveBeanClass()方法

doResolveBeanClass()方法详解

@Nullable
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
		throws ClassNotFoundException {

	ClassLoader beanClassLoader = getBeanClassLoader();
	ClassLoader dynamicLoader = beanClassLoader;
	boolean freshResolve = false;

	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) {
			dynamicLoader = tempClassLoader;
			freshResolve = true;
			if (tempClassLoader instanceof DecoratingClassLoader) {
				DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
				for (Class<?> typeToMatch : typesToMatch) {
					dcl.excludeClass(typeToMatch.getName());
				}
			}
		}
	}

	String className = mbd.getBeanClassName();
	if (className != null) {
		// 解析Spring表达式,有可能直接返回了一个Class对象
		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) {
				className = (String) evaluated;
				freshResolve = true;
			} else {
				throw new IllegalStateException("Invalid class name expression result: " + evaluated);
			}
		}
		if (freshResolve) {
			// When resolving against a temporary class loader, exit early in order
			// to avoid storing the resolved Class in the bean definition.
			if (dynamicLoader != null) {
				try {
					return dynamicLoader.loadClass(className);
				} catch (ClassNotFoundException ex) {
					if (logger.isTraceEnabled()) {
						logger.trace("Could not load class [" + className + "] from " + dynamicLoader + ": " + ex);
					}
				}
			}
			return ClassUtils.forName(className, dynamicLoader);
		}
	}

	// Resolve regularly, caching the result in the BeanDefinition...
	return mbd.resolveBeanClass(beanClassLoader);
}

通过上诉代码,我们可以看到:

  1. 优先返回当前线程中的ClassLoader;
  2. 线程中类加载器为null的情况下,返回ClassUtils类的类加载器;
  3. 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器;
  4. 返回resolveBeanClass()方法

resolveBeforeInstantiation()方法

resolveBeforeInstantiation()方法详解

/**
 * 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.
		// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
		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;
}

  通过上述方法,我们可以看到,首先会判断Bean对象是否实现了InstantiationAwareBeanPostProcessor接口,如果实现了InstantiationAwareBeanPostProcessor接口,会调用它的postProcessBeforeInstantiation方法,返回postProcessBeforeInstantiation方法的执行结果;
  返回createBean()方法;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值