三、Bean实例化
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
destroyBeans();
// Reset 'active' flag.
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
6、registerBeanPostProcessors(beanFactory)
将容器中已经定义的实现了BeanPostProcessor接口的实现类按照特定的顺序注册到容器中,如注册拦截bean创建的后置处理器CommonAnnotationBeanPostProcessor AutowiredAnnotationBeanPostProcessor,还有一些自定义实现BeanPostProcessor接口都注册到容器中,并在后续创建bean的时候调用。
7、initMessageSource
初始化messageSource组件,用来做国际化,消息绑定,消息解析
8、initApplicationEventMulticaster()
向容器中注册基于事件开发的事件多播器对象
9、onrefresh()
空方法,留给子类继承实现个性换配置的
10、registerListeners()
将所有的监听器对象添加到多播器对象中,以便后续对事件的派发
11、finishBeanFactoryInitialization(beanFactory)
实例化所有剩余的(非懒加载)单例
在preInstantiateSingletons方法中会调用getBean去创建实例化bean。
我们着重看doGetBean方法,先从单例缓存中找,没有找到会先判断是否是正在创建的bean
Object sharedInstance = getSingleton(beanName);
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 先从单例缓存中找,没有找到会先判断是否是正在创建的bean
// isSingletonCurrentlyInCreation 判断对应的单例对象是否在创建中
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// earlySingletonObjects中保存所有提前曝光的单例,尝试从earlySingletonObjects中找
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
// 如果允许早期依赖,可以尝试从singletonFactories中找到对应的单例工厂
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
//创建bean,并缓存提前曝光的bean,就是还未进行属性注入的bean,用于解决循环依赖
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
然后会去判断bean = getObjectForBeanInstance(sharedInstance, name, beanName, null)是普通bean还是factoryBean,如果是factoryBean那么就调用FactoryBean的getObject()方法返回bean而不用去实例化。
object = factory.getObject()
需要去标注该bean正在被创建,防止多个线程同时创建名称相同的bean对象。
if (!typeCheckOnly) {
// 标记 bean要创建了
markBeanAsCreated(beanName);
}
循环依赖问题:A有B的属性,而B有A的属性,那么getBean(A),获取到A的实例,此时还未进行注入;当开始注入,发现B属性,开始getBean(B),获取到B的实例;开始对B注入,发现A属性,这样就可以获取到还未注入完成的A。也就是在构建单例的时候,会将还未完成注入的A提前暴露,便于B完成注入。
这里就是依赖类的创建
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
判断是否为单例,如果是单例并去实例化bean
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
先了解什么是BeanPostProcessor,BeanPostProcessor是Spring容器的一个扩展点,可以进行自定义的实例化、初始化、依赖装配、依赖 检查等流程,即可以覆盖默认的实例化,也可以增强初始化、依赖注入、依赖检查等流程。
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
在创建bean的时候会经过9个BeanPostProcessor的调用,现在重点看createBean方法,
1、第一次调用后置处理器
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
// 直接返回替代的对象实例,不再实例化目标对象
return bean;
}
实例化前的后置处理器调用 InstantiationAwareBeanPostProcessor,通过如上代码可以进行实例化的预处理(自定义实例化bean,如创建相应的代理对象)和后处理(如 进行自定义实例化的bean的依赖装配)。一般该bean如果是被AOP增强过的话,就会返回一个代理bean对象。调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法
2、第二次调用后置处理器
是在doCreateBean中调用,执行该方法后bean的实例也就创建出来了。
instanceWrapper = createBeanInstance(beanName, mbd, args);
确定要为给定bean使用的候选构造器,检查所有已注册的构造器,实现类 AutowiredAnnotationBeanPostProcessor,扫描@Autowired修饰的构造器,判断创建对象所用的构造 器(deafult,primary)。调用SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors方法
3、第三次调用后置处理器
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
允许后置处理器修改合并的bean定义 ,实现类AutowiredAnnotationBeanPostProcessor,用于扫描 @Autowired和@Value修饰的属性和方法,封装到InjectionMetadata。调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition。
4、第四次调用后置处理器
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
获得提前暴露的bean引用。主要用于解决循环引用的问题,只有单例对象才会调用此方法。调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference方法
5、第五次,六次调用后置处理器
populateBean(beanName, mbd, instanceWrapper)
第五次:
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
continueWithPropertyPopulation = false;
break;
}
}
}
}
调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法
在目标对象实例化之后调用,此时对象被实例化,但是对象的属性还未设置。如果该方法返回fasle,则 会忽略之后的属性设置。返回true,按正常流程设置属性值 。
第六次:
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
可以在该方法内对属性值进行修改(此时属性值还未设置,但可以修改原本会设置的进去的属性值),如果postProcessAfterInstantiation方法返回false,该方法不会调用。使用了@Autowired 属性注入是调用AutowiredAnnotationBeanPostProcessor
6、第七,八次调用后置处理器
exposedObject = initializeBean(beanName, exposedObject, mbd)
三种初始化方法
在@Bean注解中执行,在实例方法上添加注解@PostConstruct,实现InitializingBean接口。
第七次:
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName)
在方法内还会执行bean生命周期回调的init方法,还会实现InitializingBean接口的调用,因为RequestMappingHandlerMapping的父类实现了InitializingBean接口,所以这里会完成RequestMapping的注册。
如果配置了@PostConstruct 会调用InitDestroyAnnotationBeanPostProcessor
((InitializingBean) bean).afterPropertiesSet();
第八次:
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
这里主要是aop的实现,AbstractAutoProxyCreator调用postProcessAfterInitialization
7、第九次调用后置处理器
registerDisposableBeanIfNecessary(beanName, bean, mbd)
确定给定的bean实例是否需要销毁后处理器,DestructionAwareBeanPostProcessor bean的销毁后置处理器
12、finishRefresh()
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
initLifecycleProcessor()方法初始化和生命周期有关的bean后处理器,我们可以写一个LifecycleProcessor接口的实现类,容器刷新完毕,就会调回调该接口的onrefresh()方法,如果是容器关闭,那就会调用该接口的onclose()方法。
getLifecycleProcessor().onRefresh()拿到前面定义的生命周期处理器,回调onRefresh()方法
publishEvent()该方法发布容器刷新完成事件
总结:
实现BeanFactoryPostProcessor接口,初始化BeanFactory时候会调用。
实现InitializingBean接口,bean在初始化的时候调用afterPropertiesSet();
实现BeanPostProcessor,可以在每个bean前后调用一次。
使用init-method初始化的方法执行。
实现FactoryBean工厂接口自定义的bean初始化。
实现DisposableBean接口,销毁bean时调用