继续前面的话题,当我们已经将bean的定义从xml文件获取到容器后(包括使用注解的自动扫描),下面要进行的就是bean的获取了。现在我们的容器拥有了bean的所有信息,包括类型,class对象,属性参数,单例or原型,初始化参数,注入参数注入类型等等,那么我们是不是就可以获取这个bean的对象了?直接从源码开始:
看下DefaultListableBeanFactory的成员变量,可以看到前两篇文章谈到的bean加载,都已经加载并放在了相应变量容器中。
/** Map from serialized id to factory instance */
private static final Map<String, Reference<DefaultListableBeanFactory>> serializableFactories =
new ConcurrentHashMap<String, Reference<DefaultListableBeanFactory>>(8);
/** Optional id for this factory, for serialization purposes */
private String serializationId;
/** Whether to allow re-registration of a different definition with the same name */
private boolean allowBeanDefinitionOverriding = true;
/** Whether to allow eager class loading even for lazy-init beans */
private boolean allowEagerClassLoading = true;
/** Optional OrderComparator for dependency Lists and arrays */
private Comparator<Object> dependencyComparator;
/** Resolver to use for checking if a bean definition is an autowire candidate */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
/** Map from dependency type to corresponding autowired value */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<Class<?>, Object>(16);
/** Map of bean definition objects, keyed by bean name */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(64);
/** Map of singleton and non-singleton bean names, keyed by dependency type */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** Map of singleton-only bean names, keyed by dependency type */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64);
/** List of bean definition names, in registration order */
private volatile List<String> beanDefinitionNames = new ArrayList<String>(64);
/** List of names of manually registered singletons, in registration order */
private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16);
/** Cached array of bean definition names in case of frozen configuration */
private volatile String[] frozenBeanDefinitionNames;
/** Whether bean definition metadata may be cached for all beans */
private volatile boolean configurationFrozen = false;
根据bean的name获取bean对象,调用DefaultListableBeanFactory的getBean方法,实际是调用父类AbstractBeanFactory的方法:
@Override
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
继续跟踪:
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, final Class<T> requiredType,
final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// Eagerly check singleton cache for manually registered singletons.
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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dependsOnBean : dependsOn) {
if (isDependent(beanName, dependsOnBean)) {
throw new BeanCreationException(mbd.getResourceDescription(),
beanName,
"Circular depends-on relationship between '"
+ beanName + "' and '" + dependsOnBean + "'");
}
registerDependentBean(dependsOnBean, beanName);
getBean(dependsOnBean);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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.