本文核心内容:分析 ①容器的创建;②配置文件的加载
一,容器的创建(XML)
故事的开始从这一行代码开始
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
查看构造方法
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
//核心方法
refresh();
}
}
进入refresh(),里面有容器加载的主流程一系列方法,本文主要分析obtainFreshBeanFactory();
本文主要讲该方法 obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新容器
refreshBeanFactory();
return getBeanFactory();
}
刷新容器的内部实现:
public abstract class AbstractRefreshableApplicationContext {
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
//创建bean工厂
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
//加载bean定义信息 重点分析
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
}
首先我们来弄清楚,ApplicationContext与BeanFactory的层级关系:
BeanFactory:
applicationContext:
可以看到,applicationContext继承了BeanFactory。
BeanFactory的主要功能是 getBean(..),获取Bean对象
ApplicationContext的主要功能:①获取对象工厂BeanFactory,②管理对象生成的生命周期。
在加载对象定义信息(beanDefinition)前,再了解下,定义信息之间的关系:
注解方式获取的对象定义信息:AnnotatedBeanDefinition
配置文件获取的对象定义信息:GenericBeanDefinition
@configuration对象定义信息:ConfigurationClassBeanDefinition
二,XML配置文件的加载:
xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions{
//解析默认标签
parseDefaultElement(ele, delegate);
//解析自定义/外部标签
delegate.parseCustomElement(ele);
}
将定义在XML文件中的标签元素信息,解析加载封装成 BeanDefinition,注册到BeanFactory中;
DefaultListableBeanFactory{
//存储BeanDefinition,key-beanName
Map<String, BeanDefinition> beanDefinitionMap;
}
(
在解析自定义标签的时候,是从spring.handlers文件中获取到
spring.handlers路径的指定,是在注册beanDefinition时:
XmlBeanDefinitionReader{
registerBeanDefinitions{
//..
createReaderContext(resource);->{
//..
new DefaultNamespaceHandlerResolver(cl);->{
// String DEFAULT_HANDLER_MAPPINGS_LOCATION
// = "META-INF/spring.handlers";
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
//..
}
//..
}
}
);
spring.handlers文件的格式是:标签定义地址=处理器完全限定名
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler