配置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 类继承关系图:
用 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 类的继承关系:
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;
}
三、总结


