SpringIoC依赖注入的过程(六)

SpringIoC依赖注入的过程(六)

    前几篇文章详细地解读了Spring的依赖注入的过程,触发依赖注入的是getBean方法,依赖注入发生的地方是populateBean方法,而获取依赖bean的实例还是通过getBean方法。截止到上文已经解读完populateBean的全部逻辑,本文介绍下,依赖注入之后bean的初始化操作。回到AbstractAutowireCapableBeanFactory的doCreateBean方法,populateBean方法之后紧接着是initializeBean,它的源码如下
	protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged(new PrivilegedAction<Object>() {
				public Object run() {
					invokeAwareMethods(beanName, bean);
					return null;
				}
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		
		Object wrappedBean = bean;
		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);
		}

		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}
		return wrappedBean;
	}
    第一步先调用各种aware接口的相关set方法,将相关的信息设置到bean中。这里被设置的对象可以有三个,分别是beanName、beanClassLoader以及beanFactory,如下代码:
	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) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());
			}
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}
   向bean中设置完beanFactory等信息之后,就是通过applyBeanPostProcessorsBeforeInitialization方法在初始化bean之前调用相关的后置处理器做一些事情。那么各种后置处理器都做了什么呢?我们看一下几个重要的后置处理的postProcessBeforeInitialization方法。在ApplicationContextAwareProcessor中,该方法调用实现了上下文相关的aware接口(ApplicationContextAware、ResourceLoaderAware等)的set方法,将上下文相关信息设置到bean中,具体的代码就不在这里粘了。InitDestroyAnnotationBeanPostProcessor中调用 PostConstruct方法,代码如下:
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
		try {
			metadata.invokeInitMethods(bean, beanName);
		}
		catch (InvocationTargetException ex) {
			throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
		}
		catch (Throwable ex) {
			throw new BeanCreationException(beanName, "Couldn't invoke init method", ex);
		}
		return bean;
	}
   还记得 SpringIoC依赖注入的过程(二)中,后置处理器通过postProcessMergedBeanDefinition找到 PostConstruct方法,这里就是对其进行了调用。
  初始化过程在调用过每个后置处理器的postProcessBeforeInitialization后置处理器之后,通过invokeInitMethods继续执行剩余的初始化动作。
	protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
			throws Throwable {

		boolean isInitializingBean = (bean instanceof InitializingBean);
		if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
			if (logger.isDebugEnabled()) {
				logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
						public Object run() throws Exception {
							((InitializingBean) bean).afterPropertiesSet();
							return null;
						}
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}				
			else {
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null) {
			String initMethodName = mbd.getInitMethodName();
			if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.isExternallyManagedInitMethod(initMethodName)) {
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}
   这里会执行两类初始化方法,一个是实现 InitializingBean接口而实现其中的afterPropertiesSet方法,还有就是我们在BeanDefinition中自己指定的初始化方法(即在配置文件中声明的init-method)。若bean实现了InitializingBean就回调其 afterPropertiesSet方法;然后通过反射调用 init-method。初始化的最后任务就是在bean初始化方法执行完毕之后再次调用bean的后置处理器,这次调用它们的postProcessAfterInitialization方法。
    好啦,现在我们得到bean是一个实例化好的、依赖注入过得并且初始化后的对象。而bean的依赖注入过程也就全部结束了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值