Spring中Bean实例化过程中的initializeBean方法

本文详细解析了Spring框架中Bean的初始化过程,包括invokeAwareMethods、applyBeanPostProcessorsBeforeInitialization、invokeInitMethods及applyBeanPostProcessorsAfterInitialization等关键步骤,并介绍了各步骤的具体作用。

populateBean方法执行后,就开始执行initializeBean方法了。在这之前前面已经完成了Bean的属性设置、依赖注入,这里属于bean初始化过程的后置部分。给用户提供一个入口,实现其他特性。

方法源码如下所示:

// AbstractAutowireCapableBeanFactory
protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	// JDK安全校验机制
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	// bean后置处理器的postProcessBeforeInitialization方法
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
	// 初始化方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	// bean后置处理器的postProcessAfterInitialization方法
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

如上代码所示,这里主要核心有四个步骤:invokeAwareMethods、applyBeanPostProcessorsBeforeInitialization、invokeInitMethods以及applyBeanPostProcessorsAfterInitialization。

① invokeAwareMethods方法

private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

源码如上所示,其将会分别尝试触发:

  • ((BeanNameAware) bean).setBeanName(beanName);-设置BeanName
  • ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);–设置Bean加载器
  • ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);–设置BeanFactory

② applyBeanPostProcessorsBeforeInitialization

applyBeanPostProcessorsBeforeInitialization方法会循环遍历BeanPostProcessor并调用其postProcessBeforeInitialization方法。

在这里插入图片描述
CommonAnnotationBeanPostProcessor其继承自InitDestroyAnnotationBeanPostProcessor实现了InstantiationAwareBeanPostProcessor接口。那么在这里就会反射调用那些被标注了@PostConstruct注解的方法,也可以看到其是在init-method方法执行前。


③ invokeInitMethods

protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
		throws Throwable {
// 是否为InitializingBean,也就是是否实现了InitializingBean接口
	boolean isInitializingBean = (bean instanceof InitializingBean);
	if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
		}
		if (System.getSecurityManager() != null) {
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
		// 调用其afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}
	}

	if (mbd != null && bean.getClass() != NullBean.class) {
		String initMethodName = mbd.getInitMethodName();
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
				// 尝试反射调用initMethod 初始化方法
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

也就是说invokeInitMethods方法将会分别尝试触发:

  • ((InitializingBean) bean).afterPropertiesSet();
  • invokeCustomInitMethod(beanName, bean, mbd);

applyBeanPostProcessorsAfterInitialization

该方法会循环遍历BeanPostProcessor并调用其postProcessAfterInitialization方法。

同样以CommonAnnotationBeanPostProcessor为例,这里会触发其postProcessAfterInitialization调用,不过该处理器此时未做任何动作只是返回了bean。

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
	return bean;
}

总结

在调用Bean的初始化方法之前,会调用一系列的aware接口实现,把相关的BeanName、BeanClassLoader以及BeanFactory注入到Bean中区。

接着会看到对invokeInitMethods的调用,如果Bean实现了InitializingBean的接口,会调用其afterPropertiesSet方法。

最后还会判断Bean是否配置有initMethod,如果有那么通过invokeCustomInitMethod方法 来直接调用,最终完成Bean的初始化。

关于Bean的初始化/生命周期可以参考博文:
Spring中Bean的作用域与生命周期
Spring中bean的初始化和销毁几种实现方式详解
Spring中那些BeanPostProcessor在Bean实例化过程中的作用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

流烟默

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值