先看一下调用图,方便后面看代码
@Test
public void testGetBean() {
// 业务代码
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-bean.xml");
XXXX xxxx = applicationContext.getBean(XXXX.class);
}
org.springframework.context.support.AbstractApplicationContext
public <T> T getBean(Class<T> requiredType) throws BeansException {
assertBeanFactoryActive();
return getBeanFactory().getBean(requiredType);
}
org.springframework.beans.factory.support.DefaultListableBeanFactory
@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 {
// 在这一步就把bean获取到了,bean是封装在namedBean中
NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args);
if (namedBean != null) {
return namedBean.getBeanInstance();
}
// 如果当前BeanFactory获取不到,则到父BeanFactory获取
BeanFactory parent = getParentBeanFactory();
if (parent != null) {
return parent.getBean(requiredType, args);
}
throw new NoSuchBeanDefinitionException(requiredType);
}
private <T> NamedBeanHolder<T> resolveNamedBean(Class<T> requiredType, Object... args) throws BeansException {
Assert.notNull(requiredType, "Required type must not be null");
// 从名称映射缓存Map中取请求名称数组
String[] candidateNames = getBeanNamesForType(requiredType);
if (candidateNames.length > 1) {
List<String> autowireCandidates = new ArrayList<String>(candidateNames.length);
for (String beanName : candidateNames) {
// isAutowireCandidate该bean是否有资格自动注入
if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
autowireCandidates.add(beanName);
}
}
if (!autowireCandidates.isEmpty()) {
candidateNames = StringUtils.toStringArray(autowireCandidates);
}
}
if (candidateNames.length == 1) {
String beanName = candidateNames[0];
// 正常情况,通过getBean获取Bean,有点隐蔽★★★★★
// 需要注意的是bean要封装成NamedBeanHolder的形式返回★★★★★
return new NamedBeanHolder<T>(beanName, getBean(beanName, requiredType, args));
}
else if (candidateNames.length > 1) {
// 如果有多个的话,根据bean的配置是否有@Primary注解来确定查哪个bean
// 加入都有@Primary注解就报错,逻辑在方法:determinePrimaryCandidate
Map<String, Object> candidates = new LinkedHashMap<String, Object>(candidateNames.length);
for (String beanName : candidateNames) {
if (containsSingleton(beanName)) {
candidates.put(beanName, getBean(beanName, requiredType, args));
}
else {
candidates.put(beanName, getType(beanName));
}
}
// 决定到底查哪个bean,看bena的@Primary注解
String candidateName = determinePrimaryCandidate(candidates, requiredType);
if (candidateName == null) {
candidateName = determineHighestPriorityCandidate(candidates, requiredType);
}
if (candidateName != null) {
Object beanInstance = candidates.get(candidateName);
if (beanInstance instanceof Class) {
beanInstance = getBean(candidateName, requiredType, args);
}
return new NamedBeanHolder<T>(candidateName, (T) beanInstance);
}
throw new NoUniqueBeanDefinitionException(requiredType, candidates.keySet());
}
return null;
}
org.springframework.beans.factory.support.AbstractBeanFactory
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
// 调用后续方法
return doGetBean(name, requiredType, args, false);
}
protected <T> T doGetBean(
final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 首先对bean name做转换,因为有可能传的是别名
final String beanName = transformedBeanName(name);
// 定义待返回的bean引用
Object bean;
// Eagerly check singleton cache for manually registered singletons.
// 核心代码:获取单例bean
Object sharedInstance = getSingleton(beanName);
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的属性合并等,可以过
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 代码省略。。。
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) {
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;
}
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry
@Override
public Object getSingleton(String beanName) {
return getSingleton(beanName, true);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 从这里可以看到spring初始化完成以后单例bean的存储位置:singletonObjects
Object singletonObject = this.singletonObjects.get(beanName);
// 如果singletonObjects中没有&&当前bean正在创建,进入二三缓存中取
// spring在装配bean的时候设置了三级缓存,分别是:
// 一级缓存:singletonObjects
// 二级缓存:earlySingletonObjects
// 三级缓存:singletonFactories
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}