吃透Spring源码(十二):Spring initializeBean源码分析

一,initializeBean方法概述

Spring中的initializeBean()方法是doCreateBean方法三部曲的最后一步,完成initializeBean()则整个bean的创建过程才算完成,我们来看一下bean的创建过程doCreateBean()方法中三部曲:实例化(createBeanInstance),填充属性(populateBean),初始化(initializeBean)。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
		implements AutowireCapableBeanFactory {
   
     
    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {
   
     

        // 省略部分代码....
		
		// 第一步:实例化bean
		instanceWrapper = createBeanInstance(beanName, mbd, args);
	
		// 为避免后期循环依赖,提前曝露ObjectFactory到第三级缓存中。
		addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        
        // 第二步:填充属性
		populateBean(beanName, mbd, instanceWrapper);
        
		// 第三步:执行初始化逻辑
		exposedObject = initializeBean(beanName, exposedObject, mbd);
		
	}
}

本文主要分析是initializeBean初始化,关于前面两步 “实例化” 和 “填充属性” 两步,请参考:

Spring实例化(createBeanInstance)源码解析

Spring属性填充populateBean源码分析


initializeBean初始化主要分为如下几个步骤:

1、 执行aware接口invokeAwareMethods;
2、 执行BeanPostProcessor的postProcessBeforeInitialization()方法;
3、 执行初始化方法invokeInitMethods;
4、 执行BeanPostProcessor的postProcessAfterInitialization()方法;

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
   
     
		
		// Aware接口处理器,调用BeanNameAware、BeanClassLoaderAware、beanFactoryAware
		invokeAwareMethods(beanName, bean);
		
		// 调用BeanPostProcessor的postProcessBeforeInitialization方法。
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		
		// 调用初始化方法,先调用bean的InitializingBean接口方法,后调用bean的自定义初始化方法
		invokeInitMethods(beanName, wrappedBean, mbd);
		
    	// 调用BeanPostProcessor的applyBeanPostProcessorsAfterInitialization方法。
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

		//返回包装后的Bean
		return wrappedBean;
	}

我们从上面可以看到,在beanPostProcessor接口的postProcessBeforeInitialization()方法和postProcessAfterInitialization()方法都可以对最终的bean做修改或替换。

如果我们配置的有Aop代理的话,会在执行AbstractAutoProxyCreator类的postProcessAfterInitialization()方法时创建此bean代理对象,并且把此代理对象放入bean容器中。

二,执行aware接口invokeAwareMethods

这个方法就是判断一下当前bean是否实现了BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口,如果实现了,就回调相应的方法。比较简单,没啥好说的,直接看源码就行了:

private void invokeAwareMethods(String beanName, Object bean) {
   
     
		//如果 bean 是 Aware 实例
		if (bean instanceof Aware) {
   
     
			//如果bean是BeanNameAware实例
			if (bean instanceof BeanNameAware) {
   
     
				//调用 bean 的setBeanName方法
				((BeanNameAware) bean).setBeanName(beanName);
			}
			//如果bean是 BeanClassLoaderAware 实例
			if (bean instanceof BeanClassLoaderAware) {
   
     
				//获取此工厂的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
   
     
					//调用 bean 的 setBeanClassLoader 方法
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			//如果bean是 BeanFactoryAware 实例
			if (bean instanceof BeanFactoryAware) {
   
     
				// //调用 bean 的 setBeanFactory 方法
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

三,执行BeanPostProcessor的postProcessBeforeInitialization()方法

postProcessBeforeInitialization()方法会在执行init方法之前调用,遍历beanPostProcessors集合调用postProcessBeforeInitialization()方法。

	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException {
   
     

		//初始化返回结果为existingBean
		Object result = existingBean;
		//遍历 该工厂创建的bean的BeanPostProcessors列表
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
   
     
			// postProcessBeforeInitialization:在任何Bean初始化回调之前(如初始化Bean的afterPropertiesSet或自定义的init方法)
			// 将此BeanPostProcessor 应用到给定的新Bean实例。Bean已经填充了属性值。返回的Bean实例可能时原始Bean的包装器。
			// 默认实现按原样返回给定的 Bean
			Object current = processor.postProcessBeforeInitialization(result, beanName);
			// 如果 current为null
			if (current == null) {
   
     
				//直接返回result,中断其后续的BeanPostProcessor处理
				return result;
			}
			//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
			result = current;
		}
		//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
		return result;
	}

1,ApplicationContextAwareProcessor调用Aware接口方法

主要完成,判断当前bean是否实现EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware接口,如果实现则对其方法进行调用。

class ApplicationContextAwareProcessor implements BeanPostProcessor {
   
     
     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
   
     
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
   
     
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
   
     
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
   
     
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
   
     
				// 检测bean上是否实现了某个aware接口,有的话进行相关的调用
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
   
     
			invokeAwareInterfaces(bean);
		}

		return bean;
	}   
}

2,ConfigurationClassPostProcessor调用ImportAware接口方法

如果bean实现了ImportAware接口,就会设置bean的注解信息:

	public Object postProcessBeforeInitialization(Object bean, String beanName) {
   
     
			if (bean instanceof ImportAware) {
   
     
				ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
				AnnotationMetadata importingClass = ir.getImportingClassFor(ClassUtils.getUserClass(bean).getName());
				if (importingClass != null) {
   
     
					((ImportAware) bean).setImportMetadata(importingClass);
				}
			}
			return bean;
		}

3,InitDestroyAnnotationBeanPostProcessor调用被注解修饰的生命周期方法

在doCreateBean中,createBeanInstance实例化完成之后,populateBean填充属性执行之前,会执行applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName)方法:

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
   
     
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
   
     
			if (bp instanceof MergedBeanDefinitionPostProcessor) {
   
     
				MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
				bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
			}
		}
	}

目的是允许beanPostProcessor去修改合并的beanDefinition,其中会执行InitDestroyAnnotationBeanPostProcessor类的postProcessMergedBeanDefinition()方法:

	public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
   
     
		// 调用方法获取生命周期元数据并保存
		LifecycleMetadata metadata = findLifecycleMetadata(beanType);
		// 验证相关方法
		metadata.checkConfigMembers(beanDefinition);
	}

会获取当前bean中包含的被@PostContruct和@PreDestroy注解标注的方法存储在lifecycleMetadataCache的map中。


所以在InitDestroyAnnotationBeanPostProcessor类的postProcessBeforeInitialization()方法中会通过反射去调用上面缓存在lifecycleMetadataCache中的被@PostContruct注解修饰的方法:

	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, "Failed to invoke init method", ex);
		}
		return bean;
	}

四,执行初始化方法invokeInitMethods

如果bean实现了InitializingBean接口,则先执行InitializingBean接口的afterPropertiesSet方法。

然后执行xml或注解设置的init-method方法。

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
   
     
    
    // 省略部分代码...
    
	// 调用bean的afterPropertiesSet方法
	((InitializingBean) bean).afterPropertiesSet();
			
	// 在bean上调用指定的自定义init方法
	invokeCustomInitMethod(beanName, bean, mbd);
			
}

五,执行BeanPostProcessor的postProcessAfterInitialization()方法

遍历beanPostProcessors集合,执行BeanPostProcessor的后置处理器:

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
   
     

		//初始化结果对象为result,默认引用existingBean
		Object result = existingBean;
		//遍历该工厂创建的bean的BeanPostProcessors列表
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
   
     
			//回调BeanPostProcessor#postProcessAfterInitialization来对现有的bean实例进行包装
			Object current = processor.postProcessAfterInitialization(result, beanName);
			//一般processor对不感兴趣的bean会回调直接返回result,使其能继续回调后续的BeanPostProcessor;
			// 但有些processor会返回null来中断其后续的BeanPostProcessor
			// 如果current为null
			if (current == null) {
   
     
				//直接返回result,中断其后续的BeanPostProcessor处理
				return result;
			}
			//让result引用processor的返回结果,使其经过所有BeanPostProcess对象的后置处理的层层包装
			result = current;
		}
		//返回经过所有BeanPostProcess对象的后置处理的层层包装后的result
		return result;
	}

1,AbstractAutoProxyCreator生成aop代理对象

如果使用了aop代理,那么此处会生成代理对象,替换原生bean对象。

	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   
     
		if (bean != null) {
   
     
			// 根据给定bean的name和class构建出一个key
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
   
     
				// 如果它需要被代理,则需要封装指定的bean
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

首先查看是否在earlyProxyReferences缓存中存在,如果有就说明处理过了,不存在就考虑是否需要被代理,如需要则创建代理对象(对原生bean封装)。

2,ApplicationListenerDetector检测bean是否实现了ApplicationListener接口

如果bean是单例的并且实现了ApplicationListener接口,则加入到多播器中applicationEventMulticaster。

public Object postProcessAfterInitialization(Object bean, String beanName) {
   
     
		if (bean instanceof ApplicationListener) {
   
     
			// 判断当前bean是否是单例,如果是的话,直接添加到容器的监听器集合中
			Boolean flag = this.singletonNames.get(beanName);
			if (Boolean.TRUE.equals(flag)) {
   
     
				// 添加到容器的监听器集合中
				this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
			}
			// 如果不是单例的,并且又是一个嵌套的bean,那么打印日志,提示内嵌的bean只有在单例的情况下才能作为事件监听器
			
		}
		return bean;
	}

六,总结

生命周期执行顺序:

1、 @PostConstruct注解修饰的方法;
2、 InitializingBean接口的afterPropertiesSet()方法;
3、 init-method指定的方法;
4、 @PreDestroy注解修饰的方法;
5、 DisposableBean接口的destroy()方法;
6、 destory-method指定的方法;

版权声明:本文不是「本站」原创文章,版权归原作者所有 | 原文地址: