1、AbstractApplicationContext类中obtainFreshBeanFactory方法
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//获取工厂类
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新工厂
refreshBeanFactory();
//返回创建结果
return getBeanFactory();
}
//refreshBeanFactory方法本类中只是定义没有实现,子类实现
//子类:AbstractRefreshableApplicationContext#refreshBeanFactory
protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException;
2、AbstractRefreshableApplicationContext#refreshBeanFactory方法介绍
//判断工厂是否存在
if (hasBeanFactory()) {
//是否已经存在,存在则清除BeanFactory和里面的实例
//销毁Bean(里面有bean生命周期的销毁方法调用)
destroyBeans();
//关闭掉
//设置beanFactory等于null
closeBeanFactory();
}
try {
//创建bean工厂类型为DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
//为了序列化指定id,可以从id反序列化到BeanFactory对象
beanFactory.setSerializationId(getId());
//定制BeanFactory相关属性
//此处主要设置两个属性
//1、是否允许使用相同名称重新注册不同的bean实现.
//2、设置是否可以循环依赖 allowCircularReferences
customizeBeanFactory(beanFactory);
//装载bean的定义信息
**//重点** 本类定义的模板方法 由子类实现AbstractXmlApplicationContext#loadBeanDefinitions
//里面包含解析xml形式配置bean的方式,并把xml中的标签封装成BeanDefinition对象
**loadBeanDefinitions(beanFactory);**
//beanFactory属性赋值
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
3、AbstractXmlApplicationContext#loadBeanDefinitions方法详解
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
//创建xml的阅读器为指定的bean工厂,**委托模式**
**XmlBeanDefinitionReader** beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// StandardEnvironment类型的环境
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader, 允许子类提供阅读器的自定义初始化
// then proceed with actually loading the bean definitions. 然后继续实际加载bean定义
initBeanDefinitionReader(beanDefinitionReader);
//主要方法下面这个
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
//都会进入AbstractBeanDefinitionReader类
//第一节测试内容传入的资源 ClassPathXmlApplicationContext类中属性
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
//获取需要加载的xml配置文件 获取ClassPathXmlApplicationContext构造器传入的参数configLocations
String[] configLocations = getConfigLocations();
if (configLocations != null) {
//先主要看这个吧
reader.loadBeanDefinitions(configLocations);
}
}
5、AbstractBeanDefinitionReader#loadBeanDefinitions(java.lang.String…)
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
count += loadBeanDefinitions(location);
}
return count;
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
//获取路径资源
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
//主要看这里
**int count = loadBeanDefinitions(resources);**
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
return count;
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"Could not resolve bean definition resource pattern [" + location + "]", ex);
}
}
else {
// Can only load single resources by absolute URL.
Resource resource = resourceLoader.getResource(location);
int count = loadBeanDefinitions(resource);
if (actualResources != null) {
actualResources.add(resource);
}
return count;
}
}
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
//子类实现XmlBeanDefinitionReader#loadBeanDefinitions
count += loadBeanDefinitions(resource);
}
return count;
}
6、XmlBeanDefinitionReader#loadBeanDefinitions方法
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
//EncodedResource带编码的对Resource对象的封装
return loadBeanDefinitions(new EncodedResource(resource));
}
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
//获取Resource对象中的xml文件流对象
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
//InputSource是jdk中的sax xml文件解析对象
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
//主要看这
**return doLoadBeanDefinitions(inputSource, encodedResource.getResource());**
}
catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
}
finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
//把inputSource 封装成Document文件对象,这是jdk的API
Document doc = doLoadDocument(inputSource, resource);
//主要看这个方法,根据解析出来的document对象,拿到里面的标签元素封装成BeanDefinition
int count = registerBeanDefinitions(doc, resource);
if (logger.isDebugEnabled()) {
logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
}//....n多异常捕获代码省了
}
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
//委托BeanDefinitionDocumentReader类进行document的解析
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
//获取解析之前的beanDefinition的数量
int countBefore = getRegistry().getBeanDefinitionCount();
//主要看这
**documentReader.registerBeanDefinitions(doc, createReaderContext(resource));**
//相减得到此次解析得到的beanDefinition的数量
return getRegistry().getBeanDefinitionCount() - countBefore;
}
7、DefaultBeanDefinitionDocumentReader#registerBeanDefinitions方法
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
//主要看这
doRegisterBeanDefinitions(doc.getDocumentElement());
}
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);
if (this.delegate.isDefaultNamespace(root)) {
String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
if (StringUtils.hasText(profileSpec)) {
String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
return;
}
}
}
//处理前 空方法
preProcessXml(root);
//主要看这,标签具体解析过程
**parseBeanDefinitions(root, this.delegate);**
//处理后 空方法
postProcessXml(root);
this.delegate = parent;
}
8、DefaultBeanDefinitionDocumentReader#parseBeanDefinitions方法
xml形式配置bean的重点
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
if (delegate.isDefaultNamespace(root)) {
NodeList nl = root.getChildNodes();
for (int i = 0; i < nl.getLength(); i++) {
Node node = nl.item(i);
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
//默认标签解析
parseDefaultElement(ele, delegate);
}
else {
//自定义标签解析
delegate.parseCustomElement(ele);
}
}
}
}
else {
//自定义标签解析
delegate.parseCustomElement(root);
}
}
//默认标签
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
//import标签解析 不是很重要
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
//alias标签解析 别名标签 不是很重要
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
//bean标签,很重要
**else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}**
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}