User user = (User) beanFactory.getBean("user");
注:User为一普通bean
查看方法(AbstractBeanFactory#getBean
)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续查看方法(AbstractBeanFactory#doGetBean
)
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//一、提取beanName
//这里主要做了两步工作
//(1)去除name开头的所有&字符,即factoryBean的修饰符
//(2)去aliasMap查找最终的beanName
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
/*
* 这里是检查缓存中或者实例工厂中是否有对应的实例
* 原因:因为在创建单例bean的时候会存在依赖注入的情况。
* 而在创建依赖的时候为了避免循环依赖,Spring创建bean的原则是不等bean创建完成就会将创建bean的ObjectFactory提早曝光,
* 也就是将ObjectFactory加入到缓存中,一旦下个bean创建的时候需要依赖上个bean则直接使用ObjectFactory
*/
//二、直接尝试从缓存获取或者从singletonFactories中的ObjectFactory
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 + "'");
}
}
//三、当前的sharedInstance只是原始的bean状态,这里需要进一步加工处理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//四、如果没有找到,则直接创建实例
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
//只有在单例情况下才会尝试解决循环依赖
//1、原型模式下,如果存在循环依赖,将会直接报错
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
//2、如果所有已经加载的bean中不包括beanName,则尝试从parentBeanFactory中查找
BeanFactory parentBeanFactory = getParentBeanFactory();
//如果parentBeanFactory存在且当前的beanDefinitionMap不存在beanName的配置,
//就只能调用parentBeanFactory的getBean方法去加载bean了
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
//递归查找
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else if (requiredType != null) {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
else {
return (T) parentBeanFactory.getBean(nameToLookup);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
//3、手动加载bean
try {
//将存储XML配置信息的GenericBeanDefinition转换成RootBeanDefinition,
//如果BeanName是子Bean的话同时会合并父类的相关属性
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
//如果存在依赖则需要定义实例化依赖的bean
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
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
//实例化当前bean的所有依赖后便会实例化mbd本身了
//下面是根据不同的scope类型来创建mbd
//单例模式创建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);
}
//原型模式
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
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.
//8、如果传递了类型,则需要进行类型转换
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;
}
上述方法就是获取bean的核心方法,我们一步一步拆解
一、首先我们需要对传递进来的name进行转换
代码如下:
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
这里主要做了两件事
-
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; }); }
该方法就是去除name的前缀中的所有&符号,这里的&符号主要是factoryBean的修饰符,如果name带有前缀&,表示获取当前的factoryBean,而非factoryBean返回的bean实例
-
canonicalName
方法public String canonicalName(String name) { String canonicalName = name; // Handle aliasing... String resolvedName; do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }
该方法就是去别名aliasMap中查找最终的beanName,例如aliasMap中,a->c,b->c,c不指向任何bean。那么当name输入a时返回的就是c。
二、尝试从缓存中加载bean
public Object getSingleton(String beanName) {
//第二个参数true表示允许早期依赖
return getSingleton(beanName, true);
}
进一步查看
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//检查缓存中是否存在实例
Object singletonObject = this.singletonObjects.get(beanName);
//如果为空且singletonsCurrentlyInCreation存在该bean
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
//锁定singletonObjects全局变量
synchronized (this.singletonObjects) {
//从earlySingletonObjects获取bean
singletonObject = this.earlySingletonObjects.get(beanName);
//如果获取不到且允许早期依赖
if (singletonObject == null && allowEarlyReference) {
//从singletonFactories获取ObjectFactory,这是因为有时候某些方法需要提前初始化的时候会
//调用addSingletonFactory方法将对应的ObjectFactory初始化策略存储在singletonFactories
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
//如果不为空
if (singletonFactory != null) {
//调用预先设定的getObject方法
singletonObject = singletonFactory.getObject();
//记录在缓存中
this.earlySingletonObjects.put(beanName, singletonObject);
//earlySingletonObjects与singletonFactories是互斥的,因此这里需要remove
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
Spring创建bean默认情况下是单例的,因此对于一个单例bean,Spring只会创建一次,后续再获取时直接从缓存中加载。由于可能存在的循环依赖(例如A依赖B,B依赖A),因此Spring为了解决循环依赖,创建bean的原则是不等bean创建完成就将创建bean的ObjectFactory
提早曝光到缓存中,一旦下一个bean创建时候需要时直接使用ObjectFactory
。这里涉及到三级缓存
/** Cache of singleton objects: bean name to bean instance.
* 保存beanName和bean实例之间的关系,即beanName-->bean实例
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory.
* 保存beanName和创建bean的工厂之间的关系,即beanName-->ObjectFactory实例
*/
private final Map<String,