spring调用bean的初始化方法分析

1:写在前面

本文在spring通过不同的方式创建bean的基础上进行分析,作为补充,详细分析spring调用初始化方法的过程。

2:initializeBean

源码如下:

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	// 安全模式和非安全模式最终都是通过调用方法invokeAwareMethods
	// 来调用Aware的方法
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		// <2021-03-29 15:38>
		// 调用BeanNameAware,BeanClassLoaderAware,BeanFactoryAware
		// 对应的setXXX方法设置对应的信息
		invokeAwareMethods(beanName, bean);
	}

	Object wrappedBean = bean;
	// mdb不为null,且是自定义的bean
	if (mbd == null || !mbd.isSynthetic()) {
		// <2021-03-30 18:17>
		// 调用bean的后置处理器的bean初始化前方法postProcessBeforeInitialization
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		// <2021-03-30 18:18>
		// 调用用户自定义的初始化方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
		// <2021-03-30 18:20>
		// 调用bean的后置处理器的bean初始化后方法postProcessAfterInitialization
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

<2021-03-29 15:38>处参考2.1:invokeAwareMethods<2021-03-30 18:17>,<2021-03-30 18:20>处逻辑类似,是分别应用后置bean处理器初始化前和初始化后对应的方法,关于后置bean处理器可以参考这里。我们只看下<2021-03-30 18:17>,是在调用用户自定义的初始化方法前,执行后置bean处理器的postProcessBeforeInitialization方法,源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {
	// 记录当前的bean
	Object result = existingBean;
	// 获取所有的后置bean处理器
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		// 执行后置bean处理器的postProcessBeforeInitialization
		// 方法获取用户处理后的对象
		Object current = processor.postProcessBeforeInitialization(result, beanName);
		// 如果是用户处理后的对象为null,则直接返回上一个不为空
		// 的处理器的执行结果(如果第一个就是返回null,则返回的是老bean)
		if (current == null) {
			return result;
		}
		// 将返回的新bean赋值到结果对象
		result = current;
	}
	// 返回结果bean
	return result;
}

<2021-03-30 18:18>处主要是调用用户的初始化方法,具体参考2.2:invokeInitMethods

2.1:invokeAwareMethods

调用BeanNameAware,BeanFactoryAware,BeanClassLoaderAware对应的setXxx方法,源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods
private void invokeAwareMethods(final String beanName, final Object bean) {
	// 如果是Aware接口的子类
	// 根据具体的不同子接口类型,调用不同的setXxx方法
	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);
		}
	}
}

2.2:invokeInitMethods

源码如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods
protected void invokeInitMethods(String beanName, final Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
	// <2021-03-30 20:39>
	boolean isInitializingBean = (bean instanceof InitializingBean);
	// 如果是InitializingBean,则调用其afterPropertiesSet方法
	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>) () -> {
					// 调用afterPropertiesSet方法
					((InitializingBean) bean).afterPropertiesSet();
					return null;
				}, getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				throw pae.getException();
			}
		}
		else {
			// 调用afterPropertiesSet方法
			((InitializingBean) bean).afterPropertiesSet();
		}
	}
	
	if (mbd != null && bean.getClass() != NullBean.class) {
		// 获取init-method定义的初始化方法
		String initMethodName = mbd.getInitMethodName();
		// 满足以下条件则调用init-method定义的初始化方法
		// 1:有值 StringUtils.hasLength(initMethodName)
		// 2:不是InitializingBean的子类或者是方法的名字不是afterPropertiesSet !(isInitializingBean && "afterPropertiesSet".equals(initMethodName))
		// 3:!mbd.isExternallyManagedInitMethod(initMethodName),不知道判断什么
		if (StringUtils.hasLength(initMethodName) &&
				!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
				!mbd.isExternallyManagedInitMethod(initMethodName)) {
			// 调用init-method定义的方法
			invokeCustomInitMethod(beanName, bean, mbd);
		}
	}
}

<2021-03-30 20:39>处是处理InitializingBean,这是一个接口,是spring留给我们的另外一个扩展点,作用是让用户能够在bean的属性都设置完毕后做一些操作,比如验证属性设置的正确与否等,会调用其afterPropertiesSet方法,该接口定义如下:

/**
 * 当需要在所有属性都设置完毕后,执行一些操作的话,可以实现该接口
 */
public interface InitializingBean {

	/**
	 当bean的所有属性设置完毕后,会调用该方法,可以在该方法内
	 做一些诸如属性验证的操作,当然也可以是在属性设置完毕后
	 才能执行的操作
	 */
	void afterPropertiesSet() throws Exception;

}

不是特别难,只需要让我们bean实现org.springframework.beans.factory.InitializingBean接口就可以了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值