基于Spring注解的上下文初始化过程源码解析(三)
上一篇跟完了 refresh 方法中第一个重要的方法 invokeBeanFactoryPostProcessors,
这篇继续分析 refresh 方法中第二个比较重要的 finishBeanFactoryInitialization 方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
/**
* 初始化此上下文的转换服务
*/
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
/**
* 如果之前没有注册 bean 后置处理器(例如 PropertyPlaceholderConfigurer)
* 则注册默认的嵌入值解析器:此时主要用于注释属性值的解析
*/
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 获取 LoadTimeWeaverAware 的 BeanName 集合
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
// 初始化 LoadTimeWeaverAware 以允许尽早注册其变换器
getBean(weaverAwareName);
}
// 停止使用临时 ClassLoader 进行类型匹配
beanFactory.setTempClassLoader(null);
// 允许缓存所有 BeanDefinition 元数据,不期望进一步更改
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有不是懒加载的单例对象
beanFactory.preInstantiateSingletons();
} 实例化所有非懒加载的单例对象方法中包含了 getBean 方法,先看 preInstantiateSingletons 方法
public void preInstantiateSingletons() throws BeansException {
// 所有已注册的 BeanName 集合
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// 触发所有非延迟加载单例 Bean 的初始化,主要步骤为调用 getBean()方法
for (String beanName : beanNames) {
// 合并父 BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象类、是单例且不是懒加载的 Bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 判断该 Bean 是否是一个 FactoryBean
if (isFactoryBean(beanName)) {
/**
* 如果是 FactoryBean 则需要加上&才能实例化该 Bean
* 否则实例化的是该 FactoryBean 生产的对象
*/
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// 再次确认是 FactoryBean 的子类
if (bean instanceof FactoryBean) {
// 强转为父类
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
/**
* SecurityManager 不为空并且是 SmartFactoryBean 的子类
*
* SmartFactoryBean 的子类有 EagerInitFactory 和 NonPrivilegedFactoryBean
*/
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
//
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
} else {
// 是 SmartFactoryBean 的子类并且是迫切需要被实例化的
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
// 如果是迫切需要被实例化的类,则实例化
if (isEagerInit) {
getBean(beanName);
}
}
} else {
// 实例化
getBean(beanName);
}
}
}
// 触发所有适用 bean 的后初始化回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
/**
* 是 SmartInitializingSingleton 的子类
*
* EventListenerMethodProcessor 是 SmartInitializingSingleton 的子类
*/
if (singletonInstance instanceof SmartInitializingSingleton) {
// 强转为 SmartInitializingSingleton
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
} else {
// 回调 afterSingletonsInstantiated 方法
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
getBean 方法是一个空壳方法,内部调用了 doGetBean 方法
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 通过 name 获取 BeanName。这里不使用 name 直接作为 BeanName 有两个原因:
*
* 1.name 可能会以 & 字符开头,表明调用者想获取 FactoryBean 对象本身的实例,
* 而非 FactoryBean 实现类所创建的 Bean 对象实例。
* 在 BeanFactory 中,FactoryBean 的实现类和其他的 Bean 存储方式是一致的,
* 即<BeanName, BeanInstance>,BeanName中是没有 & 这个字符的,
* 所以需要将 name 的首字符 & 移除,这样才能从缓存里取到 FactoryBean 创建的实例
* 2.该 Bean 对象可能存在别名的问题
*/
// 解析 BeanName 为规范名称
final String beanName = transformedBeanName(name);
Object bean;
/**
* 解决循环依赖问题【通过两次重载的 getSingleton() 方法和一次后置处理器方法的调用来解决循环依赖】
*/
// 第一次调用 getSingleton() 方法,检查单个缓存以手动注册单例。
// 获取在给定名称下注册的(原始)单例对象。
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isTraceEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
}
}
// 获取给定 bean 实例的对象,如果是 FactoryBean,则为 bean 实例本身或其创建的对象。
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 已经创建过该实例对象
else {
// 如果已经创建了这个 bean 实例,则会失败:我们可以在循环引用中完成。
// prototype 对象在每次 get 的时候创建,单例则不需要创建
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 检查此工厂中是否存在 BeanDefinition
BeanFactory parentBeanFactory = getParentBeanFactory();
// 父工厂存在且不包含解析后的 beanName
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
// 转换调用 doGetBean 方法
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 使用显式 args 委托父级
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// 没有参数,委托标准的 getBean 方法
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 校验是否是抽象的
checkMergedBeanDefinition(mbd, beanName, args);
// 初始化当前 Bean 依赖的 Bean【被 @DependsOn 注解指明需要依赖的 Bean】
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
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 + "'");
}
// 为给定 bean 注册依赖 bean
registerDependentBean(dep, beanName);
try {
// 获取给定的 bean 实例
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) {
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// 原型则创建新的实例
Object prototypeInstance;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isTraceEnabled()) {
logger.trace("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
} FactoryBean 是一种特殊的 Bean,能产生新的 Bean,获取的时候需要加’&’字符,否则获取的是其产生的 Bean。
Spring在这一步完成了所有非延迟加载的单例对象的初始化,至此 Spring 的 BeanFactory 就初始化完成了,分析的比较浅,也没有进行总结,后面会继续补充和完善,并辅以图表和示例代码。
相关文章