相关源码注释
ApplicationContext
Spring 5 DefaultResourceLoader 源码注释
Spring 5 AbstractApplicationContext 源码注释
BeanFactory
Spring 5 SimpleAliasRegistry 源码注释
Spring 5 DefaultSingletonBeanRegistry 源码注释
Spring 5 FactoryBeanRegistrySupport 源码注释
Spring 5 AbstractBeanFactory 源码注释
Spring 5 AbstractAutowireCapableBeanFactory 源码注释
Spring 5 DefaultLisbaleBeanFactory 源码注释
getObjectForBeanInstance(sharedInstance, name, beanName, null);
从 beanInstannce 中获取公开的Bean对象,主要处理beanInstance是FactoryBean对象的情况,如果不是FactoryBean会直接 返回beanInstance实例
/**
* Get the object for the given bean instance, either the bean
* instance itself or its created object in case of a FactoryBean.
* <p>获取给定Bean实例对象,对于FactoryBean,可以是Bean实例本身,也可以
* 是它创建的对象</p>
* @param beanInstance the shared bean instance - 共享bean实例
* @param name name that may include factory dereference prefix - 可能包含工厂取消引用前缀的名字
* @param beanName the canonical bean name - 规范bean名
* @param mbd the merged bean definition - 合并的bean定义
* @return the object to expose for the bean - 为bean公开的对象
*/
protected Object getObjectForBeanInstance(
Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {
// Don't let calling code try to dereference the factory if the bean isn't a factory.
// 如果Bean不是工厂,不要让调用代码尝试取消对工厂的引用
// 如果 name为FactoryBean的解引用.name是以'&'开头,就是FactoryBean的解引用
if (BeanFactoryUtils.isFactoryDereference(name)) {
//如果beanInstance是NullBean实例
if (beanInstance instanceof NullBean) {
//返回beanInstance
return beanInstance;
}
//如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
//抛出Bean不是一个Factory异常
throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
}
//如果mbd不为null
if (mbd != null) {
//设置mbd是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
//返回beanInstance
return beanInstance;
}
// 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.
// 现在我们有了Bean实例,他可能是一个普通的Bean或FactoryBean。
// 如果它是FactoryBean,我们使用它来创建一个Bean实例,除非调用者确实需要对工厂的引用。
//如果beanInstance不是FactoryBean实例
if (!(beanInstance instanceof FactoryBean)) {
return beanInstance;
}
//定义为bean公开的对象,初始化为null
Object object = null;
//如果mbd不为null
if (mbd != null) {
//更新mbd的是否是FactoryBean标记为true
mbd.isFactoryBean = true;
}
else {
//从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
object = getCachedObjectForFactoryBean(beanName);
}
//如果object为null
if (object == null) {
// Return bean instance from factory.
// 从工厂返回Bean实例
//将beanInstance强转为FactoryBean对象
FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
// Caches object obtained from FactoryBean if it is a singleton.
// 如果是单例对象,则缓存从FactoryBean获得的对象、
//如果mbd为null && 该BeanFactory包含beanName的BeanDefinition对象。
if (mbd == null && containsBeanDefinition(beanName)) {
//获取beanName合并后的本地RootBeanDefintiond对象
mbd = getMergedLocalBeanDefinition(beanName);
}
//是否是'synthetic'标记:mbd不为null && 返回此bean定义是否是"synthetic"【一般是指只有AOP相关的prointCut配置或者
// Advice配置才会将 synthetic设置为true】
boolean synthetic = (mbd != null && mbd.isSynthetic());
//从BeanFactory对象中获取管理的对象.如果不是synthetic会对其对象进行该工厂的后置处理
object = getObjectFromFactoryBean(factory, beanName, !synthetic);
}
//返回为bean公开的对象
return object;
}
BeanFactoryUtils.isFactoryDereference(name)
返回给定名称是否为FactoryBean的解引用.判断依据:name是以’&'开头,就是FactoryBean的解引用
/**
* Return whether the given name is a factory dereference
* (beginning with the factory dereference prefix).
* <p>返回给定名称是否为FactoryBean的解引用名.(从FactoryBean的解引用前缀开始)</p>
* @param name the name of the bean -- bean名
* @return whether the given name is a factory dereference -- 给定名称是否为BeanFactory的解引用
* @see BeanFactory#FACTORY_BEAN_PREFIX
*/
public static boolean isFactoryDereference(@Nullable String name) {
//如果有传入bean名且bean名是以'&'开头,则返回true,表示是BeanFactory的解引用,否则
// 返回false,表示不是BeanFactory的解引用
return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX));
}
getCachedObjectForFactoryBean(beanName)
org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getCachedObjectForFactoryBean(String beanName)
从FactoryBean获得的对象缓存集中获取beanName对应的Bean对象
/**
* Cache of singleton objects created by FactoryBeans: FactoryBean name to object.
* <p>由FactoryBeans创建的单例对象的缓存:FactoryBean名称到对象</p>
* */
private final Map<String, Object> factoryBeanObjectCache = new ConcurrentHashMap<>(16);
/**
* Obtain an object to expose from the given FactoryBean, if available
* in cached form. Quick check for minimal synchronization.
* <p>获取要从给定的FactoryBean公开的对象(如果以缓存的形式可用)。快速检查最小
* 同步</p>
* @param beanName the name of the bean -- bean名
* @return the object obtained from the FactoryBean,
* or {@code null} if not available
* -- 从FactoryBean获得的对象;如果不可用,则为null
*/
@Nullable
protected Object getCachedObjectForFactoryBean(String beanName) {
return this.factoryBeanObjectCache.get(beanName);
}
containsBeanDefinition(beanName)
org.springframework.beans.factory.support.AbstractBeanFactory # containsBeanDefinition(String beanName) 是个抽象方法:
/**
* Check if this bean factory contains a bean definition with the given name.
* Does not consider any hierarchy this factory may participate in.
* Invoked by {@code containsBean} when no cached singleton instance is found.
* <p>该BeanFactory是否包含beanName的BeanDefinition对象。不考虑工厂可能参与的任何层次结构。
* 未找到缓存的单例实例时,由{@code containsBena}调用。</p>
* <p>Depending on the nature of the concrete bean factory implementation,
* this operation might be expensive (for example, because of directory lookups
* in external registries). However, for listable bean factories, this usually
* just amounts to a local hash lookup: The operation is therefore part of the
* public interface there. The same implementation can serve for both this
* template method and the public interface method in that case.
* <p>根据具体bean工厂实现的性质,此操作可能很昂贵(例如,由于在外部注册表中进行目录
* 寻找)。但是,对应可列出的bean工厂,这通常只相当于本地哈希查找:因此,该操作是该处
* 工厂接口的一部分。在这种情况下,该模板方法和公共接口方法都可以使用相同的实现。</p>
* @param beanName the name of the bean to look for - 要查找的bean名
* @return if this bean factory contains a bean definition with the given name
* - 如果此bean工厂包含具有给定名称的bean定义。
* @see #containsBean
* @see org.springframework.beans.factory.ListableBeanFactory#containsBeanDefinition
*/
protected abstract boolean containsBeanDefinition(String beanName);
由 DefaultListableBeanFactory 实现:
/**
* Map of bean definition objects, keyed by bean name.
* <p>Bean定义对象的映射,以Bean名称为键</p>
* */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
/**
* 本地工厂中BeanDefinition对象映射【beanDefinitionMap】中是否存在beanName该键名
* @param beanName the name of the bean to look for -- 要寻找的bean名
*/
@Override
public boolean containsBeanDefinition(String beanName) {
//如果beanName为null,抛出异常
Assert.notNull(beanName, "Bean name must not be null");
//从Beand定义对象映射中判断beanName是否存在该键
return this.beanDefinitionMap.containsKey(beanName);
}
getMergedLocalBeanDefinition(beanName)
获取beanName合并后的本地RootBeanDefintiond
Spring 5 AbstractBeanFactory – getMergedLocalBeanDefinition 源码解析
getObjectFromFactoryBean(factory, beanName, !synthetic)
从BeanFactory对象中获取管理的对象.可根据shouldPostProcess对其对象进行该工厂的后置处理
Spring 5 AbstractBeanFactory – getObjectFromFactoryBean 源码解析