说 XmlBeanDefinitionReader前先说说关于他的继承体系:
BeanDefinitionReader接口
public interface BeanDefinitionReader {
// 获取bean注册器
BeanDefinitionRegistry getRegistry();
// 获取资源加载器
@Nullable
ResourceLoader getResourceLoader();
// 获取类加载器
@Nullable
ClassLoader getBeanClassLoader();
// 获取bean名称生成器
BeanNameGenerator getBeanNameGenerator();
// 加载bean
int loadBeanDefinitions(Resource var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(Resource... var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String var1) throws BeanDefinitionStoreException;
int loadBeanDefinitions(String... var1) throws BeanDefinitionStoreException;
}
AbstractBeanDefinitionReader抽象类
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
// 打印日志对象
protected final Log logger = LogFactory.getLog(this.getClass());
// bean注册器
private final BeanDefinitionRegistry registry;
// 资源加载器
@Nullable
private ResourceLoader resourceLoader;
// 类加载器
@Nullable
private ClassLoader beanClassLoader;
// 编码环境
private Environment environment;
// bean名称生成器
private BeanNameGenerator beanNameGenerator;
// 构造器(bean注册器)
protected AbstractBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 获取bean名称生成器
this.beanNameGenerator = DefaultBeanNameGenerator.INSTANCE;
// 判断bean注册器是否为null
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
// 注册器是否实现类型加载器接口
if (this.registry instanceof ResourceLoader) {
this.resourceLoader = (ResourceLoader)this.registry;
} else {
this.resourceLoader = new PathMatchingResourcePatternResolver();
}
// 注册器是否实现环境控制接口
if (this.registry instanceof EnvironmentCapable) {
this.environment = ((EnvironmentCapable)this.registry).getEnvironment();
} else {
this.environment = new StandardEnvironment();
}
}
// 获取bean注册器(IOC容器实现bean注册器接口,如DefaultListableBeanFactory)
public final BeanDefinitionRegistry getBeanFactory() {
return this.registry;
}
// 获取bean注册器
public final BeanDefinitionRegistry getRegistry() {
return this.registry;
}
// 设置资源加载器
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
// 获取资源加载器
@Nullable
public ResourceLoader getResourceLoader() {
return this.resourceLoader;
}
// 设置类加载器
public void setBeanClassLoader(@Nullable ClassLoader beanClassLoader) {
this.beanClassLoader = beanClassLoader;
}
// 获取类加载器
@Nullable
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
// 设置环境
public void setEnvironment(Environment environment) {
Assert.notNull(environment, "Environment must not be null");
this.environment = environment;
}
// 获取环境
public Environment getEnvironment() {
return this.environment;
}
// 设置bean名称生成器
public void setBeanNameGenerator(@Nullable BeanNameGenerator beanNameGenerator) {
this.beanNameGenerator = (BeanNameGenerator)(beanNameGenerator != null ? beanNameGenerator : DefaultBeanNameGenerator.INSTANCE);
}
// 获取bean名称生成器
public BeanNameGenerator getBeanNameGenerator() {
return this.beanNameGenerator;
}
// 加载bean(资源路径信息)
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
Resource[] var3 = resources;
int var4 = resources.length;
for(int var5 = 0; var5 < var4; ++var5) {
Resource resource = var3[var5];
count += this.loadBeanDefinitions((Resource)resource);
}
return count;
}
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(location, (Set)null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException("Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
} else {
int count;
if (resourceLoader instanceof ResourcePatternResolver) {
try {
Resource[] resources = ((ResourcePatternResolver)resourceLoader).getResources(location);
count = this.loadBeanDefinitions(resources);
if (actualResources != null) {
Collections.addAll(actualResources, resources);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
}
return count;
} catch (IOException var6) {
throw new BeanDefinitionStoreException("Could not resolve bean definition resource pattern [" + location + "]", var6);
}
} else {
Resource resource = resourceLoader.getResource(location);
count = this.loadBeanDefinitions((Resource)resource);
if (actualResources != null) {
actualResources.add(resource);
}
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
}
return count;
}
}
}
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
String[] var3 = locations;
int var4 = locations.length;
for(int var5 = 0; var5 < var4; ++var5) {
String location = var3[var5];
count += this.loadBeanDefinitions(location);
}
return count;
}
}
AbstractBeanDefinitionReader抽象类有三个实现类:GroovyBeanDefinitionReader,PropertiesBeanDefinitionReader,XmlBeanDefinitionReader。今天主要说说XmlBeanDefinitionReader的实现逻辑。
XmlBeanDefinitionReader
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
// 没有验证
public static final int VALIDATION_NONE = 0;
// 自动验证
public static final int VALIDATION_AUTO = 1;
// 验证 DTD
public static final int VALIDATION_DTD = 2;
// 验证 XSD
public static final int VALIDATION_XSD = 3;
//
private static final Constants constants = new Constants(XmlBeanDefinitionReader.class);
// 验证方式
private int validationMode = 1;
// 命名空间感知
private boolean namespaceAware = false;
// 从xml中读取bean的Document读取器
private Class<? extends BeanDefinitionDocumentReader> documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
// 问题报告者
private ProblemReporter problemReporter = new FailFastProblemReporter();
// 读者事件监听器
private ReaderEventListener eventListener = new EmptyReaderEventListener();
// 源提取器
private SourceExtractor sourceExtractor = new NullSourceExtractor();
// 命名空间处理程序解析器
@Nullable
private NamespaceHandlerResolver namespaceHandlerResolver;
// Document加载器
private DocumentLoader documentLoader = new DefaultDocumentLoader();
// 实体解析器
@Nullable
private EntityResolver entityResolver;
// 错误处理程序
private ErrorHandler errorHandler;
// Xml 验证模式检测器
private final XmlValidationModeDetector validationModeDetector;
// 当前线程存储的资源编码
private final ThreadLocal<Set<EncodedResource>> resourcesCurrentlyBeingLoaded;
// 构造器(
// this.reader = new XmlBeanDefinitionReader(this);
// 在XmlBeanFactory中创建XmlBeanFactory时将自己作为参数传递
// 由于DefaultListableBeanFactory实现了BeanDefinitionRegistry接口
// 在加上XmlBeanFactory继承了DefaultListableBeanFactory类所以
// XmlBeanFactory也就有了bean的注册功能,本身也是BeanDefinitionRegistry的子类)
public XmlBeanDefinitionReader(BeanDefinitionRegistry registry) {
// 初始化父类构造器
super(registry);
// 获取错误处理器
this.errorHandler = new SimpleSaxErrorHandler(this.logger);
// 获取验证模式检测器
this.validationModeDetector = new XmlValidationModeDetector();
// 创建ThreadLocal
this.resourcesCurrentlyBeingLoaded = new NamedThreadLocal<Set<EncodedResource>>("XML bean definition resources currently being loaded") {
protected Set<EncodedResource> initialValue() {
return new HashSet(4);
}
};
}
// 设置验证
public void setValidating(boolean validating) {
this.validationMode = validating ? 1 : 0;
this.namespaceAware = !validating;
}
// 设置验证模式名称
public void setValidationModeName(String validationModeName) {
this.setValidationMode(constants.asNumber(validationModeName).intValue());
}
public void setValidationMode(int validationMode) {
this.validationMode = validationMode;
}
public int getValidationMode() {
return this.validationMode;
}
public void setNamespaceAware(boolean namespaceAware) {
this.namespaceAware = namespaceAware;
}
public boolean isNamespaceAware() {
return this.namespaceAware;
}
public void setProblemReporter(@Nullable ProblemReporter problemReporter) {
this.problemReporter = (ProblemReporter)(problemReporter != null ? problemReporter : new FailFastProblemReporter());
}
public void setEventListener(@Nullable ReaderEventListener eventListener) {
this.eventListener = (ReaderEventListener)(eventListener != null ? eventListener : new EmptyReaderEventListener());
}
public void setSourceExtractor(@Nullable SourceExtractor sourceExtractor) {
this.sourceExtractor = (SourceExtractor)(sourceExtractor != null ? sourceExtractor : new NullSourceExtractor());
}
public void setNamespaceHandlerResolver(@Nullable NamespaceHandlerResolver namespaceHandlerResolver) {
this.namespaceHandlerResolver = namespaceHandlerResolver;
}
public void setDocumentLoader(@Nullable DocumentLoader documentLoader) {
this.documentLoader = (DocumentLoader)(documentLoader != null ? documentLoader : new DefaultDocumentLoader());
}
public void setEntityResolver(@Nullable EntityResolver entityResolver) {
this.entityResolver = entityResolver;
}
protected EntityResolver getEntityResolver() {
if (this.entityResolver == null) {
ResourceLoader resourceLoader = this.getResourceLoader();
if (resourceLoader != null) {
this.entityResolver = new ResourceEntityResolver(resourceLoader);
} else {
this.entityResolver = new DelegatingEntityResolver(this.getBeanClassLoader());
}
}
return this.entityResolver;
}
public void setErrorHandler(ErrorHandler errorHandler) {
this.errorHandler = errorHandler;
}
public void setDocumentReaderClass(Class<? extends BeanDefinitionDocumentReader> documentReaderClass) {
this.documentReaderClass = documentReaderClass;
}
// 加载bean方法,在XmlBeanFactory中就调用此方法开始进行IOC 的初始化工作
// 从xml中加载bean,解析bean,将bean注册到IOC容器中
// Resource 资源路径
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 创建资源编码对象将资源对象作为参数
return this.loadBeanDefinitions(new EncodedResource(resource));
}
// 加载bean(资源编码对象--包含了资源对象)
public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
// 判断资源编码对象是否为null
Assert.notNull(encodedResource, "EncodedResource must not be null");
if (this.logger.isTraceEnabled()) {
this.logger.trace("Loading XML bean definitions from " + encodedResource);
}
// 获取当前线程中所有的资源编码对象
Set<EncodedResource> currentResources = (Set)this.resourcesCurrentlyBeingLoaded.get();
// 判断当前资源编码对象是否已经存在
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException("Detected cyclic loading of " + encodedResource + " - check your import definitions!");
} else {
// 定义int类型的var6
int var6;
try {
// 从资源编码对象中获取资源对象在获取输入流
InputStream inputStream = encodedResource.getResource().getInputStream();
Throwable var4 = null;
try {
// 创建资源输入流将从资源对象中获取的输入流作为参数
InputSource inputSource = new InputSource(inputStream);
// 判断资源编码对象的编码是否不为null
if (encodedResource.getEncoding() != null) {
// 设置资源输入流的编码类型
inputSource.setEncoding(encodedResource.getEncoding());
}
// 开始加重bean(资源输入流,资源对象),返回bean的个数
var6 = this.doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} catch (Throwable var24) {
var4 = var24;
throw var24;
} finally {
if (inputStream != null) {
if (var4 != null) {
try {
inputStream.close();
} catch (Throwable var23) {
var4.addSuppressed(var23);
}
} else {
inputStream.close();
}
}
}
} catch (IOException var26) {
throw new BeanDefinitionStoreException("IOException parsing XML document from " + encodedResource.getResource(), var26);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
return var6;
}
}
public int loadBeanDefinitions(InputSource inputSource) throws BeanDefinitionStoreException {
return this.loadBeanDefinitions(inputSource, "resource loaded through SAX InputSource");
}
public int loadBeanDefinitions(InputSource inputSource, @Nullable String resourceDescription) throws BeanDefinitionStoreException {
return this.doLoadBeanDefinitions(inputSource, new DescriptiveResource(resourceDescription));
}
// 开始加重bean(资源输入流,资源对象)
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException {
try {
// 通过资源资源输入流和资源对象从xml解析出包含bean的Document对象
Document doc = this.doLoadDocument(inputSource, resource);
// 对包含bean的Docuemnt对象进行解析并注册到IOC容器中,返回bean的个数
int count = this.registerBeanDefinitions(doc, resource);
if (this.logger.isDebugEnabled()) {
// 加载bean的个数来自 resource
this.logger.debug("Loaded " + count + " bean definitions from " + resource);
}
return count;
} catch (BeanDefinitionStoreException var5) {
throw var5;
} catch (SAXParseException var6) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + var6.getLineNumber() + " in XML document from " + resource + " is invalid", var6);
} catch (SAXException var7) {
throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", var7);
} catch (ParserConfigurationException var8) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, var8);
} catch (IOException var9) {
throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, var9);
} catch (Throwable var10) {
throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, var10);
}
}
// 加载Docuemnt对象(资源输入流,资源对象)
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
// 委托DocumentLoader对象的loadDocument方法获取Document对象
return this.documentLoader.loadDocument(inputSource, this.getEntityResolver(), this.errorHandler, this.getValidationModeForResource(resource), this.isNamespaceAware());
}
protected int getValidationModeForResource(Resource resource) {
int validationModeToUse = this.getValidationMode();
if (validationModeToUse != 1) {
return validationModeToUse;
} else {
int detectedMode = this.detectValidationMode(resource);
return detectedMode != 1 ? detectedMode : 3;
}
}
protected int detectValidationMode(Resource resource) {
if (resource.isOpen()) {
throw new BeanDefinitionStoreException("Passed-in Resource [" + resource + "] contains an open stream: cannot determine validation mode automatically. Either pass in a Resource that is able to create fresh streams, or explicitly specify the validationMode on your XmlBeanDefinitionReader instance.");
} else {
InputStream inputStream;
try {
inputStream = resource.getInputStream();
} catch (IOException var5) {
throw new BeanDefinitionStoreException("Unable to determine validation mode for [" + resource + "]: cannot open InputStream. Did you attempt to load directly from a SAX InputSource without specifying the validationMode on your XmlBeanDefinitionReader instance?", var5);
}
try {
return this.validationModeDetector.detectValidationMode(inputStream);
} catch (IOException var4) {
throw new BeanDefinitionStoreException("Unable to determine validation mode for [" + resource + "]: an error occurred whilst reading from the InputStream.", var4);
}
}
}
// 向IOC容器中注册bean(包含bean的Document对象,和资源对象)
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 从Document中读取bean的对象
BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader();
// 获取注册器XmlBeanFactory由于XmlBeanFactory继承DefaultListableBeanFactory
// 从而调用的是DefaultListableBeanFactory中的getBeanDefinitionCount方法
// public int getBeanDefinitionCount() {
// return this.beanDefinitionMap.size();
// } 会发现返回的是装载Bean的Map的大小
int countBefore = this.getRegistry().getBeanDefinitionCount();
// 调用documentReader的registerBeanDefinitions方法对Document进行解析并且对bean
// 进行注册
documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
// 返回扩容大小
return this.getRegistry().getBeanDefinitionCount() - countBefore;
}
// 创建从document中读取bean的对象
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
return (BeanDefinitionDocumentReader)BeanUtils.instantiateClass(this.documentReaderClass);
}
// 创建上下文读取器
public XmlReaderContext createReaderContext(Resource resource) {
return new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, this.getNamespaceHandlerResolver());
}
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
if (this.namespaceHandlerResolver == null) {
this.namespaceHandlerResolver = this.createDefaultNamespaceHandlerResolver();
}
return this.namespaceHandlerResolver;
}
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = this.getResourceLoader() != null ? this.getResourceLoader().getClassLoader() : this.getBeanClassLoader();
return new DefaultNamespaceHandlerResolver(cl);
}
}