上文Spring源码深度解析(XmlBeanFactory源码解析上)介绍了XMLBeanFactory加载beans.xml的全过程
简单总结一下就是:
读取beans.xml为输入流;
DOM解析xml文件为Document;
Spring解析Document的Element为BeanDefinitionHolder;
将beanName和BeanDefinitionHolder的键值对放入DefaultListableBeanFactory类的beanDefinitionMap中。
本文接着上文来介绍
Student bean = (Student) bf.getBean("student");
上述一句代码所实现的操作
注意:由于Bean的xml可配置项较多,生产Bean的方式也较多,纵观BeanFactory.getBean()相关操作的代码分叉较多,笔者不会分析所有的代码分支情况,只会按照最简约的模式来分析最核心的代码,这样不会迷失在代码的海洋里。。。
1.XMLBeanFactory的基本使用
代码同 Spring容器的基本实现(XmlBeanFactory源码解析上) 1小结代码
2.写在分析XmlBeanFactory源码之前
由上节可知,解析后的beanName和BeanDefinitionHolder的键值对放入DefaultListableBeanFactory类的beanDefinitionMap中,beanDefinitionMap结构是一个默认大小为256的ConcurrentHashMap
按照最简单的实现方式:
1)BeanFactory.getBean(String beanName)无非就是根据beanName从ConcurrentHashMap中获取对应的value值,也就是BeanDefinitionHolder实例
2)获取BeanDefinitionHolder中的BeanDefinition,获取BeanDefinition对应的Class对象
3)反射获取Class对象所对应的实体类对象bean
4)返回调用
由以上方式是可以获取beanName对应的bean实例,但是还有些问题需要我们来思考
问题:
* bean的实现由prototype和singleton的区别,如何区别实现?
* bean的实现过程中,若依赖其他bean该如何加载?
* 若bean之间循环依赖该如何解决?
...
3.XmlBeanFactory.getBean(String name)代码结构分析 public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
// 1.转换name,因为name有可能是FactoryBean相关的name,也有可能是alias,所以需要判断
final String beanName = transformedBeanName(name);
Object bean;
// 2.如果是单例模式创建的bean,如果bean已经被创建过则会放入singletonFactories,
// 此时再获取则从singletonFactories中直接获取
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);
}
// 3.bean没有被创建过,重新开始创建
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// parentBeanFactory默认为空,该段逻辑不走
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) {
// 3.1将beanName添加到已创建的列表中,表明该bean已经在创建中了。
markBeanAsCreated(beanName);
}
try {
// 3.2 根据beanName获取对应的BeanDefinition,然后重新包装成RootBeanDefinition
// (重要方法,在这个方法里会从DefaultListableBeanFactory类的beanDefinitionMap中获取对应的BeanDefinitionHolder)
// 此处刚好衔接
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 3.3 获取该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);
}
}
// 3.4 单例模式下的bean实例创建(最重要的方法,最终的bean实例创建在这)
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
@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);
}
// 3.5原型模式下的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);
}
// 3.6 按照给定模式来创建
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() {
@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);
}
}
}
...
}
...
return (T) bean;
}
总结:纵观以上代码,大致可分为两部分:
1)已创建过该单例实例,则直接从singletonFactories中去取(singletonFactories是一个Map结构,key为name,value为ObjectFactory)
2)没有创建过该实例,则重新创建,按照bean的scope类型来创建,prototype和singleton类型分别有不同的实现方式
下面按照这两部分逐一介绍,先介绍没有创建该实例的情况
4.初次创建实例代码分析 1)根据beanName来获取BeanDefinition,并封装RootBeanDefinition(对应于3代码片段中的3.2小结)
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
...
// getMergedLocalBeanDefinition()
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException {
// 1.判断是否已经被创建过,如果已被创建过,则可以直接在mergedBeanDefinitions获取
RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName);
if (mbd != null) {
return mbd;
}
// 2.新建
return getMergedBeanDefinition(beanName, getBeanDefinition(beanName));// 重要方法
}
// getBeanDefinition(),通过该方法来获取beanDefinitionMap对应的BeanDefinition
// 具体实现在DefaultListableBeanFactory.getBeanDefinition(String beanName)方法
public BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException {
BeanDefinition bd = this.beanDefinitionMap.get(beanName);//直接从beanDefinitionMap即可
if (bd == null) {
if (this.logger.isTraceEnabled()) {
this.logger.trace("No bean named '" + beanName + "' found in " + this);
}
throw new NoSuchBeanDefinitionException(beanName);
}
return bd;
}
// getMergedBeanDefinition(),封装RootBeanDefinition
protected RootBeanDefinition getMergedBeanDefinition(
String beanName, BeanDefinition bd, BeanDefinition containingBd)
throws BeanDefinitionStoreException {
synchronized (this.mergedBeanDefinitions) {
RootBeanDefinition mbd = null;
// 1.先尝试从mergedBeanDefinitions获取,若已添加过该RootBeanDefinition,则会添加到mergedBeanDefinitions
if (containingBd == null) {
mbd = this.mergedBeanDefinitions.get(beanName);
}
// 2.mbd和bd.getParentName()都是null,
if (mbd == null) {
if (bd.getParentName() == null) {
// Use copy of given root bean definition.
if (bd instanceof RootBeanDefinition) {
mbd = ((RootBeanDefinition) bd).cloneBeanDefinition();
}
else {
// 2.1直接走该逻辑,剩余代码直接略过
mbd = new RootBeanDefinition(bd);
}
}
...
// 3.如果scope为空,则默认描述为单例模式
if (!StringUtils.hasLength(mbd.getScope())) {
mbd.setScope(RootBeanDefinition.SCOPE_SINGLETON);
}
...
}
return mbd;
}
}
总结1):由上述过程可知,主要流程是:
* 先从DefaultListableBeanFactory类的beanDefinitionMap中根据beanName获取对应的BeanDefinition
* 将BeanDefinition封装一层,封装为RootBeanDefinition返回
2)对该bean依赖的其他bean进行创建(对应于3代码片段中的3.3小结)
// 1.获取该bean所依赖的所有beanName
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 + "'");
}
// 2.将dep注册到dependentBeanMap中
registerDependentBean(dep, beanName);
// 3.循环getBean()方法,也就是重复当前bean的创建过程
getBean(dep);
}
}
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
总结2):主要过程也就是获取当前bean依赖的所有bean,然后依次调用getBean()方法,重复当前bean的获取过程
3)创建单例实例(对应于3代码片段中的3.3小结)重要方法
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
try {
// 该方法被回调,真正创建bean的方法在此处
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
// getSingleton()
public Object getSingleton(String beanName, ObjectFactory singletonFactory) {
Assert.notNull(beanName, "'beanName' must not be null");
synchronized (this.singletonObjects) {
// 1.先从singletonObjects获取
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
...
boolean newSingleton = false;
boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
if (recordSuppressedExceptions) {
this.suppressedExceptions = new LinkedHashSet();
}
try {
// 2.主要方法,会回调getSingleton()方法的getObject()方法
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
...
finally {
if (recordSuppressedExceptions) {
this.suppressedExceptions = null;
}
afterSingletonCreation(beanName);
}
if (newSingleton) {
// 3.将singletonObject放入singletonObjects
addSingleton(beanName, singletonObject);
}
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
下面来查看最重要的回调方法getSingleton()方法中的 getObject()方法
getObject()方法直接调用createBean()方法,这是一个抽象方法,默认实现类为AbstractAutowireCapableBeanFactory
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 1.获取beanName对应的class
Class resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
...
// 2.获取class对应的实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// doCreateBean()
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 1.创建bean实例(重要方法)
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
...
Object exposedObject = bean;
try {
// 2.初始化bean属性
populateBean(beanName, mbd, instanceWrapper);
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
...
return exposedObject;
}
//createBeanInstance()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
// 1.获取class
Class beanClass = resolveBeanClass(mbd, beanName);
...
// 调用bean的无参构造函数
return instantiateBean(beanName, mbd);
}
// instantiateBean()
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
try {
Object beanInstance;
final BeanFactory parent = this;
...
else {
// 重要方法,获取bean实例
beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
}
BeanWrapper bw = new BeanWrapperImpl(beanInstance);
initBeanWrapper(bw);
return bw;
}
...
}
// instantiate()
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
// Don't override the class with CGLIB if no overrides.
if (bd.getMethodOverrides().isEmpty()) {
Constructor constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 1.获取Class对象
final Class clazz = bd.getBeanClass();
...
}
}
// 2.调用instantiateClass来获取实例,实际就是通过反射来获取
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}
// 最终通过Constructor的反射来获取对应实例
public static T instantiateClass(Constructor ctor, Object... args) throws BeanInstantiationException {
Assert.notNull(ctor, "Constructor must not be null");
try {
ReflectionUtils.makeAccessible(ctor);
// 反射获取
return ctor.newInstance(args);
}
...
}
总结3):可知,最终是通过bean的构造函数,来反射获取对应的实例的
总结4:纵观上述过程,再与之前的XMLBeanFactory构造方法结合起来,实际整个过程:
1)从DefaultListableBeanFactory类的beanDefinitionMap中获取对应的BeanDefinition
2)获取BeanDefinition中的class
3)通过bean的构造函数,来反射获取该实例
5.再次获取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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
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);
}
总结5:再次获取bean单例实例的逻辑就比较简单了,就是直接从singletonObjects中来获取对应的Object,由于之前创建的已经存在于singletonObjects,所以直接返回即可
参考:Spring源码深度解析(郝佳)