刚开始阅读spring源码的时候很痛苦,主要是spring的框架实在是太庞大,其实在阅读一个框架的源码时很忌讳的就是全局看,应该在了解其基本原理的情况下去看其部分的源码,比如了解了SpringMVC,那么你就可以专心的看SpringMVC的模块。
我们知道spring的核心就是IOC和AOP,那么在IOC中,Bean是IOC依赖注入的基本单位,BeanFactoy是Bean的容器,其中最重要的方法就是getBean了,那么容器是如何一步一步获取Bean的。
在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);
}
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {
return doGetBean(name, requiredType, args, false);
}
重写的getBean方法都会调用doGetBean方法。doGetBean方法很长,我把它分成以下几个部分:
- 首先从单例缓存(单例Bean有一个raw instance)中获取Bean的原始引用
- 如果对象缓存有我们所需要的Bean对象的引用,那获取Bean的引用,进行循环依赖检查,判断Bean是否为FactoryBean,若是FactoryBean,则按照FactroyBean中工厂方法来返回对象,若不是FactoryBean,则直接返回实例。
- 如果单例对象缓存中没有,那么接下来就是创建这个Bean
- 接着检查父容器有没有这个Bean,如果父容器有这个Bean且本容器中没有此Bean的定义,则交给父容器去获取这个Bean,最终由父容器返回Bean
- 若果父容器中没有此Bean的定义,则先检查此Bean初始化所需要的依赖Bean,先获取此Bean所需要依赖的Bean
- 根据Bean的scope来决定获取Bean对象实例的方法
- 若是Singleton类型,则现在单例实例缓存中查找,如果没有则创建,并加入到缓存,最终返回该实例
- 如果是Prototype,则直接创建Bean实例,并返回
- 标记Bean已经创建
- 如果参数中给了返回对象实例的类型,则去判断我们得到的Bean是否是所给的参数类型
接下来就来结合代码来详细的看一下
@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;
// 首先根据给的beanName在单例对象实例中查找
Object sharedInstance = getSingleton(beanName);
//如果该bean在单例实例中存在,则返回该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类型是否为FactoryBean,如果是FactoryBean的话,则按照FactoryBean中定义的获取
//bean的方法来获取bean,如果不是FactoryBean则直接返回该bean实例
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
// 如果单例实例缓存中没有此bean,则创建bean
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 在父容器中检查是否有该bean的定义,如果有则交给父容器来创建
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);
// 可能我们创建的bean也依赖与其他的bean,所以在创建此bean必须先获取该bean所依赖的bean
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);
}
}
// 根据bean的scope来决定创建bean的方式
if (mbd.isSingleton()) {
//在单例对象实例缓存中得到有该bean对象实例
//此方法中,如果没有该bean的对象实例,则创建该bean(该函数的第二个匿名内部类就是用于创建bean)
//创建该bean后,再把它加入到单例对象缓存中,以便下次获取singleton类型的时候,直接返回
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);
}
//如果是prototype类型,则创建bean对象实例
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, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
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;
}
}
// 检查我们得到的bean对象是否是我们所给的对象类型
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中获取Bean的逻辑就分析完毕了,中间可能有错误,望指出。