本文会介绍上文中提到的<1>,<2>,<3>这三个步骤的内容
1 transformedBeanName
final String beanName = transformedBeanName(name);
这段代码的作用主要有两个:
1.如果传入的bean name是别名,那么就要获取对应的真实的bean name。也会存在循环别名即别名B指向别名A,别名A指向真实的bean name的情况。
2.去掉"&"符号,获取真实的bean name。如:name从"&MyBean"变成"MyBean"。
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
public static String transformedBeanName(String name) {
Assert.notNull(name, "'name' must not be null");
if (!name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) {
return name;
}
// 循环去掉前面所有的 & 符号
return transformedBeanNameCache.computeIfAbsent(name, beanName -> {
do {
beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length());
}
while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
return beanName;
});
}
public String canonicalName(String name) {
String canonicalName = name;
// Handle aliasing...
String resolvedName;
do {
// 递归获取别名对应的beanName
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
2 getSingleton
spring为了避免创建单例时出现循环依赖的问题,所以创建bean的时候不等bean创建完成就会创建bean的ObjectFactory提早曝光加入到缓存中,一旦下一个bean创建时需要依赖这个bean就直接使用ObjectFactory。
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从单例缓存中加载 bean
Object singletonObject = this.singletonObjects.get(beanName);
// 缓存中的 bean 为空,且当前 bean 正在创建(注:第七步创建单例类型bean的时候会保存在一个缓存中)
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
// 从 earlySingletonObjects 获取,表示此bean正在创建,不进行后续处理
singletonObject = this.earlySingletonObjects.get(beanName);
// earlySingletonObjects 中没有,且允许提前创建
if (singletonObject == null && allowEarlyReference) {
// 从 singletonFactories 中获取对应的 ObjectFactory
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
// 获得 bean
// 对应第7步中的 getEarlyBeanReference(beanName, mbd, bean)
singletonObject = singletonFactory.getObject();
// 添加 bean 到 earlySingletonObjects 中
this.earlySingletonObjects.put(beanName, singletonObject);
// 从 singletonFactories 中移除对应的 ObjectFactory
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
最大的难点可能在于其中的好几个map对象到底是什么意思,下面来简单介绍下:
1.singletonObjects(一级缓存):保存beanName与bean实例之间的关系。
那么这个里面的数据来自哪里呢?答案在 bean 加载过程中的第7步
DefaultSingletonBeanRegistry#getSingleton(创建单例模式的java bean)
-> DefaultSingletonBeanRegistry#addSingleton方法
protected void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
从二级和三级缓存中删除,添加到一级缓存中
2.earlySingletonObjects(二级缓存):也是保存beanName与bean实例之间的关系,与singletonObjects不同的地方是,当bean还在创建过程中的时候就可以通过这个map拿到对应的bean实例,相当于保存的是半成品的bean,用来检测循环引用。
3.singletonFactories(三级缓存):保存beanName与创建bean的工厂之间的关系。这个map中的数据来源于,bean 加载过程中的第7步
AbstractAutowireCapableBeanFactory#createBean
-> AbstractAutowireCapableBeanFactory#doCreateBean
-> DefaultSingletonBeanRegistry#addSingletonFactory
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(singletonFactory, "Singleton factory must not be null");
synchronized (this.singletonObjects) {
if (!this.singletonObjects.containsKey(beanName)) {
this.singletonFactories.put(beanName, singletonFactory);
this.earlySingletonObjects.remove(beanName);
this.registeredSingletons.add(beanName);
}
}
}
从三级缓存中删除,加入二级缓存。由此可以看到二级缓存和三级缓存其实是互斥的
总的三级缓存的使用逻辑大概是:
在A的创建过程中会添加三级缓存,然后进行A的属性填充,如果此时A依赖了B,那么需要首先创建B。当B的创建又需要用到A,就会从三级缓存中获取,然后通过singletonFactory.getObject()获取初始A对象(没有初始化和填充属性,但是经过了AOP代理),放入二级缓存并且删除三级缓存,返回半成品的A作为B的属性,然后B的创建就完成了。返回A的创建中,当A创建完成后,删除二级和三级缓存,之后的A获取都可以在一级缓存中拿到。
从这里可以看出来,就算是使用一级和二级缓存也能实现解决循环依赖的问题,那为什么还要使用三级缓存呢?原因主要是:二级缓存放入的是实例化后的半成品对象,如果这个对象还需要实现AOP功能,那么就需要使用ObjectFactory包装然后放入三级缓存中。然后在第三步的getObjectForBeanInstance方法中,取出ObjectFactory包装的AOP之后的对象。
3 getObjectForBeanInstance
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// 若为工厂类引用(name 以 & 开头)
// Don't let calling code try to dereference the factory if the bean isn't a factory.
if (BeanFactoryUtils.isFactoryDereference(name)) {
if (beanInstance instanceof NullBean) {
return beanInstance;
}
// 类型不为 FactoryBean
if (!(beanInstance instanceof FactoryBean)) {
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
}
// 到这里就有了一个 Bean 实例,当然该实例可能是会是一个正常的 bean 又或者是一个 FactoryBean
// 如果是 FactoryBean 并且 name 中有 & 符号,则直接返回,否则使用 FactoryBean 创建bean
// Now we have the bean instance, which may be a normal bean or a FactoryBean.
// If it's a FactoryBean, we use it to create a bean instance, unless the
// caller actually wants a reference to the factory.
if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) {
return beanInstance;
}
Object object = null;
// 若 BeanDefinition 为 null,则从缓存中加载 Bean 对象
if (mbd == null) {
object = getCachedObjectForFactoryBean(beanName);
}
// 若 object 依然为空,则可以确认,beanInstance 一定是 FactoryBean 。从而,使用 FactoryBean 获得 Bean 对象
if (object == null) {
// Return bean instance from factory.
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// containsBeanDefinition 检测 beanDefinitionMap 中也就是在所有已经加载的类中
// 检测所有已经加载的bean是否包含 beanName
if (mbd == null && containsBeanDefinition(beanName)) {
// 将存储 XML 配置文件的 GenericBeanDefinition 转换为 RootBeanDefinition,
// 如果指定 BeanName 是子 Bean 的话同时会合并父类的相关属性
mbd = getMergedLocalBeanDefinition(beanName);
}
// 是否是用户定义的,而不是应用程序本身定义的
boolean synthetic = (mbd != null && mbd.isSynthetic());
// 核心处理方法,使用 FactoryBean 获得 Bean 对象
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
return object;
}
其中最核心的是getObjectFromFactoryBean,接下来看看这个方法。
protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) {
// 为单例模式且缓存中存在
if (factory.isSingleton() && containsSingleton(beanName)) {
synchronized (getSingletonMutex()) {
// 从缓存中获取指定的 factoryBean
Object object = this.factoryBeanObjectCache.get(beanName);
if (object == null) {
// 为空,则从 FactoryBean 中获取对象
object = doGetObjectFromFactoryBean(factory, beanName);
// Only post-process and store if not put there already during getObject() call above
// (e.g. because of circular reference processing triggered by custom getBean calls)
Object alreadyThere = this.factoryBeanObjectCache.get(beanName);
if (alreadyThere != null) {
object = alreadyThere;
}
else {
// 需要后续处理
if (shouldPostProcess) {
// 若该 Bean 处于创建中,则返回非处理对象,而不是存储它
if (isSingletonCurrentlyInCreation(beanName)) {
// Temporarily return non-post-processed object, not storing it yet..
return object;
}
// 单例 Bean 的前置处理
// 设置该bean正在创建过程中
beforeSingletonCreation(beanName);
try {
// 对从 FactoryBean 获取的对象进行后处理
// 生成的对象将暴露给 bean 引用
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName,
"Post-processing of FactoryBean's singleton object failed", ex);
}
finally {
// 单例 Bean 的后置处理
// 移除该bean正在创建
afterSingletonCreation(beanName);
}
}
// 添加到 factoryBeanObjectCache 中,进行缓存
if (containsSingleton(beanName)) {
this.factoryBeanObjectCache.put(beanName, object);
}
}
}
return object;
}
}
else {
// 为空,则从 FactoryBean 中获取对象
Object object = doGetObjectFromFactoryBean(factory, beanName);
// 需要后续处理
if (shouldPostProcess) {
try {
// 对从 FactoryBean 获取的对象进行后处理
// 生成的对象将暴露给 bean 引用
object = postProcessObjectFromFactoryBean(object, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Post-processing of FactoryBean's object failed", ex);
}
}
return object;
}
}
这里把这个代码拆分成if和else看。
3.1 if块代码
当bean是单例的并且已经存在缓存中。获取同步锁,如果能够获取到对应的FactoryBean就直接返回,否则通过传入的factory#getObject获取对象并且进行后置处理。
3.1.1 doGetObjectFromFactoryBean
权限验证以及通过 factory#getObject 方法获取对象。
3.1.2 后置处理
3.1.2.1 beforeSingletonCreation
protected void beforeSingletonCreation(String beanName) {
if (!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
}
校验当前bean没有在检测并且设置正在创建
3.1.2.2 postProcessObjectFromFactoryBean
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
// 获取 BeanPostProcessor 数组
for (BeanPostProcessor processor : getBeanPostProcessors()) {
// 循环调用 postProcessAfterInitialization 方法,如果为空立即返回
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
BeanPostProcessor 也就是后置处理器,可用于类增强。后续专门介绍
3.1.2.3 afterSingletonCreation
校验当前bean没有在检测并且移除正在创建
3.2 else
bean不是单例对象,直接通过 factory#getObject 方法获取对象,并且进行后置处理。