概述
本系列源码都是基于spring-4.3.8版本之上,其他版本略有差异,但总体的核心思想相同。同时,为了使贴出的源代码尽可能的紧凑,可能会删去一些异常捕获、日志输出等代码。若文中存在纰漏错误,欢迎指正。
先看一下BeanFactory中定义的所有getBean方法
Object getBean(String name) throws BeansException;
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
Object getBean(String name, Object... args) throws BeansException;
<T> T getBean(Class<T> requiredType, Object... args) throws BeansException;
以上五个getBean方法中,所有带beanName参数的方法都在AbstractBeanFactory中实现了,其余的两个也在DefaultListableBeanFactory中实现了。
AbstractBeanFactory中的getBean
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
@Override
public Object getBean(String name, Object... args) throws BeansException {
return doGetBean(name, null, args, false);
}
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
DefaultListableBeanFactory中的getBean
@Override
public <T> T getBean(Class<T> requiredType) throws BeansException {
return getBean(requiredType, (Object[]) null);
}
@Override
public <T> T getBean(Class<T> requiredType, Object... args) throws BeansException {
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return parent.getBean(requiredType, args);
}
throw new NoSuchBeanDefinitionException(requiredType);
}
可以看出除了DefaultListableBeanFactory#getBean(Class<T> requiredType, Object... args)之外,其他的方法都是通过直接通过AbstractBeanFactory#doGetBean获取bean的。
那么我们再重新看一下这个看似不同的getBean方法
public <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType) throws BeansException {
// 调用当前类的resolveNamedBean获取NamedBeanHolder
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, (Object[]) null);
if (namedBean != null) {
return namedBean;
}
// 若获取不到,则获取parentBeanFactory,以parentBeanFactory#resolveNamedBean获取NamedBeanHolder
BeanFactory parent = getParentBeanFactory();
if (parent instanceof AutowireCapableBeanFactory) {
return ((AutowireCapableBeanFactory) parent).resolveNamedBean(requiredType);
}
throw new NoSuchBeanDefinitionException(requiredType);
}
看来关键还是得看DefaultListableBeanFactory#resolveNamedBean
@SuppressWarnings("unchecked")
private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
// 以beanClass换取beanName,即通过该bean的类型从allBeanNamesByType中获取beanName
// 候选者beanName数组
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
List<String> autowireCandidates = new ArrayList<String>(candidateNames.length);
// 通过beanName获取BeanDefinition,且BeanDefinition#autowireCandidate为true即可加入候选组,该值默认即true
for (String beanName : candidateNames) {
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
// 将经过筛选的候选者重新赋值到candidateNames
if (!autowireCandidates.isEmpty()) {
candidateNames = autowireCandidates.toArray(new String[autowireCandidates.size()]);
}
}
// 候选者若只有一个,那直接以该beanName通过AbstractBeanFactory#getBean获取bean实例
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
// 依然是以beanName从AbstractBeanFactory#getBean获取bean实例
return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
}
// 若候选者不止一个,则需要重新选举最合适的
else if (candidateNames.length > 1) {
Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length);
for (String beanName : candidateNames) {
if (containsSingleton(beanName)) {
// 依然是以beanName从AbstractBeanFactory#getBean获取bean实例
candidates.put(beanName, getBean(beanName, requiredType, args));
} else {
candidates.put(beanName, getType(beanName));
}
}
// 首先通过AbstractBeanDefinition#primary筛选候选者
String candidateName = determinePrimaryCandidate(candidates, requiredType);
if (candidateName == null) {
// 若筛选失败,候选者都被淘汰时,再重新以Priority进行筛选候选者
candidateName = determineHighestPriorityCandidate(candidates, requiredType);
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance instanceof Class) {
// 依然是以beanName从AbstractBeanFactory#getBean获取bean实例
beanInstance = getBean(candidateName, requiredType, args);
}
return new NamedBeanHolder<T>(candidateName, (T) beanInstance);
}
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
}
return null;
}
可以看出,该方法除了最后的返回null和抛出异常结束之外,其余的出口也依然是通过AbstractBeanFactory#getBean获取实例的,所以绕了半天,其本质依然是通过AbstractBeanFactory#doGetBean获取bean实例的。
因此所有的getBean只是通过不同的传参方式调用doGetBean,其本质上还是得通过AbstractBeanFactory#doGetBean获取bean实例的,所以看来重点就是这个doGetBean方法了。
/**
* {@link AbstractBeanFactory#getBean(String)}
* {@link AbstractBeanFactory#getBean(String, Class)}
* {@link AbstractBeanFactory#getBean(String, Object...)}
* {@link AbstractBeanFactory#getBean(String, Class, Object...)}
* {@link DefaultListableBeanFactory#getBean(Class)}
* {@link DefaultListableBeanFactory#getBean(Class, Object...)}
* AbstractBeanFactory中实现了大部分的getBean,剩余的在DefaultListableBeanFactory中实现
* 而不论哪一种最终都是需要通过doGetBean获取bean实例
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args,
boolean typeCheckOnly) throws BeansException {
/**
* 对name进行解析,主要做了两件事:
* (1)将name开头的所有"&"去除,并赋值给beanName,如此一来,name负责处理与factoryBean有关的bean获取,
* 而beanName则用来获取所有其他bean。
* (2)以转换后的name调用SimpleAliasRegistry.canonicalName(String),以alias别名换取id
*/
final String beanName = transformedBeanName(name);
Object bean;
/**
* 尝试以singleton的方式调用DefaultSingletonBeanRegistry.getSingleton(String)获取bean,
* 这个方法还会以allowEarlyReference=true即允许早期引用的形式继续调用getSingleton(String beanName,
* boolean allowEarlyReference)。
* 该方法会先从一级缓存singletonObjects以及二级缓存earlySingletonObjects中获取,
* 若依然获取不到,由于allowEarlyReference=true,则会继续从三级缓存singletonFactories中获取objectFactorys,
* 若获取到了就以objectFactory#getObject的方式获取bean。 执行过程可能是以下的几种情况:
* 1、从一级缓存singletonObjects中获取bean,若获取到了说明获取的bean早就被创建好了,否则继续获取
* 2、一级缓存未获取到,继续从二级缓存earlySingletonObjects中获取,若获取到了,说明该beanName虽然已被创建完毕,
* 但还非完全实例化完毕(singletonsCurrentlyInCreation中必然存在该beanName),
* 只是提早暴露了出来而已。(而之所以会在二级缓存earlySingletonObjects中,请看(3))
* 3、一级、二级缓存中都未获取到,且allowEarlyReference=true的时候,从三级缓存singletonFactories中获取,
* 获取到的是objectFactory,若获取到了,说明当前beanName正在创建中,尚未完全创建完毕,
* 只是提前将自己的制造工厂——ObjectFactory暴露出来了而已,然后继续调用ObjectFactory#getObject获取bean,
* 一般而言,这里的ObjectFactory#getObject都是在AbstractAutowireCapableBeanFactory.doCreateBean中添加的,
* 且getObject方法是调用AbstractAutowireCapableBeanFactory.getEarlyBeanReference获取早期引用的。
* 4、三级缓存中也没有获取到,说明当前bean尚未被加载过,方法执行完毕,doGetBean继续向下执行。
*/
Object sharedInstance = getSingleton(beanName);
/**
* 根据之前的getSingleton(String)是否从缓存中获取到了bean决定如何执行:
* 1、若获取到了,则继续调用AbstractBeanFactory.getObjectForBeanInstance判断该类是否实现了FactoryBean,
* 若实现了则调用getObject获取bean,否则依然返回bean。 2、若未获取到则说明该bean尚未被初始化或者其根本就不是单例而是多例,继续执行下去
*/
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 尝试获取父容器,并从父容器中获取bean
BeanFactory parentBeanFactory = getParentBeanFactory();
// 若父容器存在,且当前容器不包含该beanName,则尝试从父容器获取bean
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 转化beanName,去除"&",并以alias别名换取id
String nameToLookup = originalBeanName(name);
// 从父容器获取bean
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
} else {
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
/**
* 用来标记当前bean是否已被创建完毕的方法,若当前bean尚未被创建,则执行完该方法,
* 其就会被加入到AbstractBeanFactory.alreadyCreated中,表示该bean已被创建或即将被创建。
* 根据doGetBean的第三个参数markBeanAsCreated决定是否执行该方法,
* 目前的所有getBean方法都默认会将typeCheckOnly设置为false,即都会执行该方法。
*/
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
/**
* 获取合并后的本地BeanDefinition,
* 根据beanName从AbstractBeanFactory#mergedBeanDefinitions中获取RootBeanDefinition,
* 若获取不到,则调用DefaultListableBeanFactory.getBeanDefinition,从beanDefinitionMap中获取BeanDefinition,
* 获取不到就抛出NoSuchBeanDefinitionException,
* 否则就继续调用AbstractBeanFactory.getMergedBeanDefinition(String, BeanDefinition)
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
/**
* 获取该bean的依赖,若存在,则逐个以DefaultSingletonBeanRegistry.registerDependentBean添加到dependentBeanMap中
* 并通过AbstractBeanFactory.getBean(String)保证当前Bean依赖的Bean全部被初始化,所以递归getBean。
*/
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 + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
}
}
/**
* 若是单例,则调用DefaultSingletonBeanRegistry#getSingleton(String, ObjectFactory<?>),
* 同时通过内部类的方式重写了ObjectFactory#getObject,
* 其会先从缓存DefaultSingletonBeanRegistry#singletonObjects中获取,
* 获取不到则说明该bean还未被实例化,以ObjectFactory#getObject继续获取该bean实例,
* 然后以匿名内部类的方式调用AbstractBeanFactory#createBean进行创建bean的操作,
* 实例化完成后,调用DefaultSingletonBeanRegistry#addSingleton将其放入缓存map-singletonObjects中,
* 这样之后调用就不会再创建了
*/
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
} catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
// 判断是否需要继续转化为FactoryBean获取bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// 若是多例,则会直接调用上述AbstractBeanFactory#createBean直接创建bean。
else if (mbd.isPrototype()) {
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
// 判断是否需要继续转化为FactoryBean获取bean
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
/**
* 若均不是,则调用AbstractBeanDefinition.getScope()获取该bean的Scope,
* 而后重写Scope#getObject并调用Scope.get(String, ObjectFactory<?>)获取bean实例,
* 最终依然会调用刚才重写的getObject并调用createBean创建bean。
*/
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
} finally {
afterPrototypeCreation(beanName);
}
}
});
// 判断是否需要继续转化为FactoryBean获取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,但是bean类型又与期待的类型不匹配时,调用TypeConverter#convertIfNecessary进行类型转换
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
} 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;
}
最后
以上就是唠叨电源为你收集整理的解析BeanFactory的核心方法——getBean的全部内容,希望文章能够帮你解决解析BeanFactory的核心方法——getBean所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复