AbstractBeanFactory在Spring中占着重要的作用,起着一个承上启下的作用。其中最重要的就是getBean方法了,就是从IOC容器中得到Bean都是在本类启动。其类图结构如下:
这里通过讲解其中重要的几个方法了解spring中BeanFactory的实现。
- getMergedLocalBeanDefinition(String beanName)方法:通过beanName得到最有的BeanDefinition。得到BeanDefinition是实例化bean的先决条件。可以看到AbstractAutowireCapableBeanFacory继承了这个AbstractBeanFactory类,而DefaultListableBeanFacotry类又基础了AbstractAutowireCapableBeanFacory。前面一篇解析xml的时候有说过解析完xml后会把BeanDefinition放在DefaultListableBeanFactory类中。所以AbstractBeanFactory类几乎可以得到DefaultListableBeanFactory中的所有属性。这里可能读者会很奇怪,为什么父类反而可以访问子类的属性呢。其实不然像我们初始化IOC容器的时候最简单的就是XmlBeanFactory,而XmlBeanFactory当然就可以访问到父类中所有可以访问到的方法和属性。spring在这其中是使用了大量的模版方法。例如在AbstractBeanFactory中有一个重要的方法,通过beanname得到BeanDefinition。
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); if (mbd != null) { return mbd; } return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); } ....... protected abstract BeanDefinition getBeanDefinition(String beanName) throws BeansException;
这里的getBeanDefinition在AbstractBeanFactory为抽象方法,可以相当BeanDefinition在解析xml的时候是向DefaultListableBeanFactory添加的。所以可以猜测getBeanDefinition应该是DefaultListableBeanFactory类中实现的,看一下果然有一个这样的方法。并且这里得到的BeanDefinition是从beanDefinitionMap中得到,至于beanDefinitionMap是怎么初始化这些beanDefinition,可以参考我前面讲解的解析xml分析。
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException { BeanDefinition bd = this.beanDefinitionMap.get(beanName); if (bd == null) { if (this.logger.isTraceEnabled()) { this.logger.trace("No bean named '" + beanName + "' found in " + this); } throw new NoSuchBeanDefinitionException(beanName); } return bd; }
- getTpye(String beanName)方法:通过beanName得到他对应的class。得到对应的class有什么作用呢,我们知道通过class,然后使用java的反射可以得到很多的东西,包括构造函数,成员变量和方法,甚至annotation。而其中得到构造方法在实例化bean如果发现auto-wire为构造函数时就是从这里获得。特别是AOP中,AOP的实现就是spring会内置一些bean,而这些bean都是通过构造方式实例化的。而不是默认的构造函数实例化然后设置一些属性。方法本身很简单。因为在BeanDefinition中解析xml的时候是有class属性的,也就是直接从BeanDefinition得到class属性。虽然其中这个方法调用过来,调用过去的。但是最终就是从BeanDefinition获得classs属性。
public Class<?> getType(String name) throws NoSuchBeanDefinitionException { String beanName = transformedBeanName(name); // Check manually registered singletons. Object beanInstance = getSingleton(beanName, false); if (beanInstance != null) { if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) { return getTypeForFactoryBean((FactoryBean) beanInstance); } else { return beanInstance.getClass(); } } else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) { // null instance registered return null; } else { // No singleton instance found -> check bean definition. BeanFactory parentBeanFactory = getParentBeanFactory(); if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { // No bean definition found in this factory -> delegate to // parent. return parentBeanFactory.getType(originalBeanName(name)); } RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); // Check decorated bean definition, if any: We assume it'll be // easier // to determine the decorated bean's type than the proxy's type. BeanDefinitionHolder dbd = mbd.getDecoratedDefinition(); if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) { RootBeanDefinition tbd = getMergedBeanDefinition( dbd.getBeanName(), dbd.getBeanDefinition(), mbd); Class targetClass = predictBeanType(dbd.getBeanName(), tbd); if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) { return targetClass; } } Class beanClass = predictBeanType(beanName, mbd); // Check bean class whether we're dealing with a FactoryBean. if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) { if (!BeanFactoryUtils.isFactoryDereference(name)) { // If it's a FactoryBean, we want to look at what it // creates, not at the factory class. return getTypeForFactoryBean(beanName, mbd); } else { return beanClass; } } else { return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null); } } }
- getBean(String name):这个就是最重要的方法了。任何通过getBean就都是调用这个方法了。这个方法也是最为复杂的。
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
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);
}
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) {
getBean(dependsOnBean);
registerDependentBean(dependsOnBean, beanName);
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
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.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 '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName,
new ObjectFactory() {
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);
}
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null
&& !requiredType.isAssignableFrom(bean.getClass())) {
throw new BeanNotOfRequiredTypeException(name, requiredType,
bean.getClass());
}
return (T) bean;
}
protected abstract Object createBean(String beanName,
RootBeanDefinition mbd, Object[] args) throws BeanCreationException;
可以看到getBean方法又调用的本身的doGetBean方法。在doGetBean中如果是第二次调用,并且bean是单例的那就直接缓存中取了。如果是第一次,流程就比较的复杂了。但是可以想到,肯定是先要得到BeanDefinition,如上标红的代码。可以看到先是检测本身的BeanFactory有没有这个bean,如果没有就从双亲中查询。如果还没有查到就一直向上找。还有如果设置了依赖会先检测依赖。最后就是在getSingleton中通过其中的参数ObjectFactory回调其中的createBean(beanName, mbd, args)方法。这里又使用了模版设计模式,这里的createBean方法是在子类AbstractAutowireCapableBeanFactory实现的。这个会在下次讲解。
- containsBean:判断当前IOC容器是否包含了指定name的bean
- isSingleton(String name):根据name判断bean是否单例
- isPrototype(String name:根据name判断bean是否为prototype
- isTypeMatch(String name, Class targetType):根据name和class类型判断bean是否为指定的class类型
- getAliases(String name):根据name活动别名
相关推荐
Spring 源代码分析系列涵盖了多个关键模块,包括事务处理、IoC容器、JDBC、MVC、AOP以及与Hibernate和Acegi安全框架的集成。以下是对这些知识点的详细阐述: 1. **Spring 事务处理**:Spring 提供了声明式事务管理...
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
通过对Spring IoC容器的理解和源码分析,我们可以深入了解到Spring框架是如何管理和控制应用对象的生命周期及依赖关系的。在实际开发中,了解Spring IoC容器的工作原理有助于更好地利用Spring框架,提高开发效率和...
通过源码分析Spring,可以帮助开发者深入理解Spring的运作机制,掌握其核心编程思想。 首先,BeanFactory是Spring中IOC容器的基础接口,它负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖关系。...
以下是对Spring源码分析中所涉及的关键知识点的详细说明。 首先,IoC容器在Spring框架中的重要性不言而喻。它是一种实现控制反转的设计模式,用来减少代码间的耦合度,提升系统的可测试性和可维护性。IoC容器能够...
rar包内含有spring2.5.6源码,解压即可使用 源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的,但当你能够看明白的时候,相信快乐也会随之而来,为了减少痛苦,更快的带来快乐,在这里希望通过这篇...
Spring源码最难问题:当Spring AOP遇上循环依赖 Spring源码中最难的问题之一是循环依赖问题,当Spring AOP遇上循环依赖时,该如何解决? Spring通过三级缓存机制解决循环依赖的问题。 在Spring中,bean的实例化...
### Spring源码分析:深入理解IOC容器 #### 一、IOC容器的概念与作用 在Spring框架中,**IOC(Inversion of Control)**容器扮演着至关重要的角色。它负责管理应用程序中的对象(即Bean)的生命周期以及依赖关系。...
n 源码分析-AbstractBeanFactory的doGetBean方法 l Spring Aop n 设计模式-代理模式 n 编程思想-AOP思想 n 基础应用-入门案例 n 基础应用-常用注解 n 高级应用-DeclareParents注解 n 高级应用-EnableLoadTimeWeaving...
Spring加载Bean: AbstractBeanFactory.xmind
在Spring的源码中,我们可以看到AbstractBeanFactory类是如何通过构造函数、setter方法或属性注解实现依赖注入的。 其次,Spring框架包含多个模块,如核心容器、数据访问/集成、Web、AOP(面向切面编程)、工具类等...
Spring框架的源代码分析主要集中在它的核心特性——控制反转(IOC)容器上。IOC容器是Spring的核心组件,它负责管理应用程序中的对象,也就是所谓的"bean"。BeanFactory接口是IOC容器的基础,它定义了最基础的bean...
春天的音符 Spring原始中文注释 BeanFactory接口继承 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean
Spring 源码解析系列将深入探讨 Spring 框架的核心机制,特别是 IOC(Inversion of Control,控制反转)和 AOP...通过阅读和分析源码,开发者可以更好地掌握 Spring 的设计原则,从而更高效地利用这个强大的框架。
这个创建过程发生在AbstractBeanFactory类的doGetBean()方法中,它会检查是否需要初始化bean,并在需要时调用createBean()方法来创建bean。 通过上述流程,AnnotationAwareAspectJAutoProxyCreator能够有效地与...
Spring还提供了更高级的容器实现,例如AbstractBeanFactory和DefaultListableBeanFactory等抽象类,它们基于模板模式,封装了BeanFactory的通用功能。此外,Spring支持通过不同的资源接口来抽象bean定义数据,使得它...
例如,`AbstractBeanFactory`和`DefaultListableBeanFactory`类提供了Bean的创建和管理功能;`BeanDefinitionRegistry`接口定义了注册Bean定义的方法;`ApplicationContext`接口则进一步封装了应用上下文的功能,如...