Spring DI 源码分析一共有五篇
Spring DI1–整体流程
Spring DI2–三级缓存获取Bean
Spring DI3–从父级BeanFactory中获取Bean
Spring DI4–创建Bean
Spring DI5–不同作用域对Bean的处理
基于Spring 5.2.6.RELEASE
由前篇Spring IOC 的第一篇的案例代码,只有Spring DI是从ApplicationContext.getBean()开始的
ApplicationContext的getBean()是继承自BeanFactory,由子类AbstractApplicationContext实现
获取Bean
//AbstractApplicationContext#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
assertBeanFactoryActive();//检查容器是否活着
return getBeanFactory().getBean(name);
}
//AbstractBeanFactory#getBean(java.lang.String)
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
//org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType, @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
//将传入的名称转换为Bean的名称,因为可能传入的是别名
final String beanName = transformedBeanName(name);
Object bean;
//获取实例 spring的三级缓存
Object sharedInstance = getSingleton(beanName);
//容器创建的实例
//缓存中已经有了初始化好的单例bean
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
//正在创建Bean,允许提前暴露的Bean,还未初始化完成
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
//获取给定Bean的实例对象,主要是完成FactoryBean的相关处理
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
//缓存中没有初始化好的单例bean
else {
//没有初始化的单例Bean,但是有正在创建的原型Bean,并且因为循环依赖创建失败了
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
//获取父级的BeanFactory
BeanFactory parentBeanFactory = getParentBeanFactory();
//当前容器的父级容器存在,且当前容器中不存在指定名称的Bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取指定BeanName的原始名称 真正的beanName 不是别名 如果这个名字带&,返回值业户带&
String nameToLookup = originalBeanName(name);
//从父级BeanFactory获取bean
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
//创建的Bean是否需要进行类型验证,上面传入的false,不需要
if (!typeCheckOnly) {
//标记Bean已经被创建
markBeanAsCreated(beanName);
}
try {
//根据指定BeanDefinition获取其父级的Beandefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
//获取当前Bean所有依赖Bean的名称
String[] dependsOn = mbd.getDependsOn();
//如果当前Bean有依赖Bean,注册所有依赖的bean(不止这个bean依赖的bean,还有这个bean依赖的bean依赖的bean),并且对所有依赖的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 + "'");
}
//注册依赖的bean
registerDependentBean(dep, beanName);
getBean(dep);
}
}
//创建单例Bean的实例对象
if (mbd.isSingleton()) {
//获取Bean实例
sharedInstance = getSingleton(beanName, () -> {
try {
//创建Bean实例对象
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//销毁对象
destroySingleton(beanName);
throw ex;
}
});
//获取Bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
//创建原型Bean实例对象
else if (mbd.isPrototype()) {
//原型Bean,每次创建一个新的对象
Object prototypeInstance = null;
try {
//调用创建前的前置方法
beforePrototypeCreation(beanName);
//创建Bea
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
//调用创建后的后知方法
afterPrototypeCreation(beanName);
}
//获取Bean
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
//要创建的Bean既不是单例模式,也不是原型模式,则根据Bean定义资源中
//配置的Bean的作用域,选择实例化Bean的合适方法
//例如web中的:request、session、application等作用域
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
//BeanDefinition中没有配置作用域
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
//获取bean实例
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);//调用前置方法
try {//创建Bea
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);//调用后置方法
}
});
//获取Bean
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;
}
}
//对Bean进行类型检查
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.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
doGetBean() 主要有以下几步:
1、获取真正的beanName;
2、从三级缓存中去获得bean;
factoryBean的处理
3、从父BeanFactory中获取Beandefinition
用父BeanFactory获取bean
4、获取BeanDefinition
注入所有依赖的bean
创建bean
单例:
创建单例bean
将bean加入缓存
factoryBean的处理
Prototype:
创建多例bean
factoryBean的处理
其他Scope:
从相应scope中获取bean并执行factorybean
5、对bean类型检查,返回bean
1、转换beanName
//转换bean名称 下面两个方法,在di中会经常用到 获取bean的真正beanName,如果是别名,通过别名缓存一层层查找
protected String transformedBeanName(String name) {
return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
1.1、转换bean名称
private static final Map<String, String> transformedBeanNameCache = new ConcurrentHashMap<>();
//org.springframework.beans.factory.BeanFactoryUtils#transformedBeanName
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;
});
}
这里判断传入的beanName是否以&符号(获取factorybean)开头,如果不是直接返回,如果是,获取&符号后面的名称,并将对应关系放入缓存中。
1.2、获取真正的名称
private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
//SimpleAliasRegistry#canonicalName
public String canonicalName(String name) {
String canonicalName = name;
String resolvedName;
do {
resolvedName = this.aliasMap.get(canonicalName);
if (resolvedName != null) {
canonicalName = resolvedName;
}
}
while (resolvedName != null);
return canonicalName;
}
这里传入的名称可能是别名,根据bean别名获取bean名称,会一层一层的查找,找到最终的bean名称