栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

【spring源码学习】获取单例bean的流程

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【spring源码学习】获取单例bean的流程

【spring源码学习】获取单例bean的流程 一、准备阶段

配置bean的xml文件,如下:




	


User类:

@Data
public class User {
	private String name;
}

UserTest类,用来测试bean是否注入进IoC容器。

class UserTest {
	@Test
	void testSimpleLoad() {
		BeanFactory bf = new ClassPathXmlApplicationContext("user.xml");
		User user = (User)bf.getBean("user");
	}
}
二、创建 ApplicationContext 的流程 2.1 ClassPathXmlApplicationContext 类

ClassPathXmlApplicationContext 类继承关系图:

2.2 创建对象

用 user.xml 创建一个 ClassPathXmlApplicationContext 一个对象:

new ClassPathXmlApplicationContext("user.xml");

调用构造函数:

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
	this(new String[] {configLocation}, true, null);
}

构造函数内调用了另一个构造函数:

public ClassPathXmlApplicationContext(
		String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
		throws BeansException {
		
	super(parent);
	setConfigLocations(configLocations);
	if (refresh) {
		refresh();
	}
}

调用父类的构造函数,ClassPathXmlApplicationContext 的父类为 AbstractXmlApplicationContext,父类的构造函数:

public AbstractXmlApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}

继续调父类的构造函数,AbstractXmlApplicationContext 的父类为 AbstractRefreshableConfigApplicationContext :

public AbstractRefreshableConfigApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}

继续调父类的构造函数,父类为 AbstractRefreshableApplicationContext :

public AbstractRefreshableApplicationContext(@Nullable ApplicationContext parent) {
	super(parent);
}

继续调调父类的构造函数:

public AbstractApplicationContext() {
	this.resourcePatternResolver = getResourcePatternResolver();
}


public AbstractApplicationContext(@Nullable ApplicationContext parent) {
	this();
	setParent(parent);
}

AbstractApplicationContext 是一个非常重要的类,需要注意的方法:

  • refresh()
  • prepareRefresh()
  • initPropertySources()
  • obtainFreshBeanFactory()
  • prepareBeanFactory()
  • postProcessBeanFactory()
  • invokeBeanFactoryPostProcessors()
  • registerBeanPostProcessors()
  • initMessageSource()
  • initApplicationEventMulticaster()
  • initLifecycleProcessor()
  • onRefresh()
  • registerListeners()
  • finishBeanFactoryInitialization()
  • finishRefresh()

需要注意的是,在 ClassPathXmlApplicationContext 构造函数的执行流程中:

// AbstractRefreshableConfigApplicationContext 的 setConfigLocations 方法
setConfigLocations(configLocations);

// refresh 为 true
// 执行 AbstractApplicationContext 的 refresh 方法
if (refresh) {
	refresh();
}

AbstractRefreshableConfigApplicationContext 的 setConfigLocations() :

public void setConfigLocations(@Nullable String... locations) {
	if (locations != null) {
		Assert.noNullElements(locations, "Config locations must not be null");
		this.configLocations = new String[locations.length];
		for (int i = 0; i < locations.length; i++) {
			this.configLocations[i] = resolvePath(locations[i]).trim();
		}
	}
	else {
		this.configLocations = null;
	}
}
三、获取单例bean的流程 3.1 AbstractApplicationContext 类

先看一下 AbstractApplicationContext 类的继承关系:

getBean 方法

assertBeanFactoryActive 方法用来判断 beanFactory 是否可用,但是目前没有做任何判断。

// AbstractApplicationContext.java
@Override
public Object getBean(String name) throws BeansException {
	assertBeanFactoryActive();
	return getBeanFactory().getBean(name);
}
3.2 AbstractRefreshableApplicationContext 类 assertBeanFactoryActive 方法

目前这个方法没有做任何判断:

@Override
protected void assertBeanFactoryActive() {
}
getBeanFactory 方法

直接返回了 beanFactory 属性:

@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
	DefaultListableBeanFactory beanFactory = this.beanFactory;
	if (beanFactory == null) {
		throw new IllegalStateException("BeanFactory not initialized or already closed - " +
				"call 'refresh' before accessing beans via the ApplicationContext");
	}
	return beanFactory;
}
3.3 AbstractBeanFactory 类 getBean 方法

执行 doGetBean方法:

@Override
public Object getBean(String name) throws BeansException {
	return doGetBean(name, null, null, false);
}
doGetBean 方法
@SuppressWarnings("unchecked")
protected  T doGetBean(
		String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
		throws BeansException {

	String beanName = transformedBeanName(name);
	Object beanInstance;

	// Eagerly check singleton cache for manually registered singletons.
	Object sharedInstance = getSingleton(beanName);
	// sharedInstance != null 为 true
	if (sharedInstance != null && args == null) {
		if (logger.isTraceEnabled()) {
			if (isSingletonCurrentlyInCreation(beanName)) {
				logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
						"' that is not fully initialized yet - a consequence of a circular reference");
			}
			else {
				logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
			}
		}
		// 调用AbstractAutowireCapableBeanFactory类的getObjectForBeanInstance方法
		beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, null);
	}

	else {
		//...暂时不用看
	}

	return adaptBeanInstance(name, beanInstance, requiredType);
}
transformedBeanName 方法
protected String transformedBeanName(String name) {
	return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}
3.4 DefaultSingletonBeanRegistry 类 getSingleton 方法
@Override
@Nullable
public Object getSingleton(String beanName) {
	return getSingleton(beanName, true);
}


@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
	// Quick check for existing instance without full singleton lock
	Object singletonObject = this.singletonObjects.get(beanName);
	
	// singletonObject != null, 下面的if代码块不用执行
	if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
		// ...这里暂时不用看
	}
	
	return singletonObject;
}
3.5 AbstractAutowireCapableBeanFactory 类 getObjectForBeanInstance 方法
@Override
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	String currentlyCreatedBean = this.currentlyCreatedBean.get();
	
	//  currentlyCreatedBean == null,下面的if代码块不执行
	if (currentlyCreatedBean != null) {
		registerDependentBean(beanName, currentlyCreatedBean);
	}

	// 调用AbstractBeanFactory类的getObjectForBeanInstance方法
	return super.getObjectForBeanInstance(beanInstance, name, beanName, mbd);
}
3.6 AbstractBeanFactory 类 getObjectForBeanInstance 方法
protected Object getObjectForBeanInstance(
		Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

	// Don't let calling code try to dereference the factory if the bean isn't a factory.
	if (BeanFactoryUtils.isFactoryDereference(name)) {
		// ...暂时不用看
	}

	// Now we have the bean instance, which may be a normal bean or a FactoryBean.
	// If it's a FactoryBean, we use it to create a bean instance, unless the
	// caller actually wants a reference to the factory.
	// 下面的判断条件为true,直接返回beanInstance
	if (!(beanInstance instanceof FactoryBean)) {
		return beanInstance;
	}
	
	// ...暂时不用看
}
adaptBeanInstance 方法
@SuppressWarnings("unchecked")
 T adaptBeanInstance(String name, Object bean, @Nullable Class requiredType) {
	// Check if required type matches the type of the actual bean instance.
	// requireType为null,以下的if代码块不执行
	if (requiredType != null && !requiredType.isInstance(bean)) {
		// ...暂时不用看
	}
	return (T) bean;
}
三、总结
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/331855.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号