"META-INF/spring.handlers" 文件的使用
// "META-INF/spring.handlers" 文件的使用
org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory()
{
// ...
DefaultListableBeanFactory beanFactory = createBeanFactory(); // 创建bean工厂 org.springframework.beans.factory.support.DefaultListableBeanFactory
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory); // 加载bean的定义文件applicationContext.xml !!!
{
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
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.
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader); // !!!
{
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations); // !!!
{
int counter = 0;
for (String location : locations) {
counter += loadBeanDefinitions(location); // !!! 迭代
{
// ...
if (resourceLoader instanceof ResourcePatternResolver) {
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); // org.springframework.context.support.AbstractApplicationContext
{
org.springframework.context.support.AbstractApplicationContext.getResources(...)
{
org.springframework.core.io.support.PathMatchingResourcePatternResolver.getResources(...)
{
// ...
}
}
}
int loadCount = loadBeanDefinitions(resources);// !!! 迭代
{
int counter = 0;
for (Resource resource : resources) {
// resource === org.springframework.core.io.UrlResource
counter += loadBeanDefinitions(resource); // !!!
{
org.springframework.beans.factory.support.XmlBeanDefinitionReader.loadBeanDefinitions(org.springframework.core.io.Resource...)
{
int counter = 0;
for (Resource resource : resources) {
// resource === org.springframework.core.io.UrlResource
counter += loadBeanDefinitions(resource); // !!! 迭代
{
org.springframework.beans.factory.xml.XmlBeanDefinitionReader.loadBeanDefinitions(org.springframework.core.io.Resource)
{
// resource === org.springframework.core.io.UrlResource
return loadBeanDefinitions(new EncodedResource(resource)); // 用EncodedResource包装UrlResource
{
// encodedResource.getResource() === org.springframework.core.io.UrlResource
InputStream inputStream = encodedResource.getResource().getInputStream(); // 文件的输入流 "/WEB-INF/applicationContext.xml"
try {
InputSource inputSource = new InputSource(inputStream); // 用InputSource包装inputStream
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());//!!!
{
// resource === org.springframework.core.io.UrlResource
Document doc = doLoadDocument(inputSource, resource); // 加载文件"/WEB-INF/applicationContext.xml"
{
return org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument()
{
DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
// entityResolver 是实体解析器
DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
// 会使用 "META-INF/spring.schemas" 文件
return builder.parse(inputSource); // 加载文件"/WEB-INF/applicationContext.xml"
}
}
return registerBeanDefinitions(doc, resource);//!!!
{
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); // org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
{
return new org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader()
}
int countBefore = getRegistry().getBeanDefinitionCount(); // org.springframework.beans.factory.support.DefaultListableBeanFactory
// resource === org.springframework.core.io.UrlResource
// documentReader === org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader
documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); // 解析dom树的节点
{
// readerContext === new XmlReaderContext(resource, this.problemReporter, this.eventListener, this.sourceExtractor, this, getNamespaceHandlerResolver());
this.readerContext = readerContext; // 读取器上下文
Element root = doc.getDocumentElement(); // "/WEB-INF/applicationContext.xml"
doRegisterBeanDefinitions(root);
{
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader.doRegisterBeanDefinitions()
{
BeanDefinitionParserDelegate parent = this.delegate;
this.delegate = createDelegate(getReaderContext(), root, parent);//!!!!
// ...
preProcessXml(root);
parseBeanDefinitions(root, this.delegate); //!!!解析xml文件
{
if (delegate.isDefaultNamespace(root)) { // org.springframework.beans.factory.xml.BeanDefinitionParserDelegate
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); // !!! 默认元素
{
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate); // 解析bean标签,bean信息添加到注册表中
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse 递归
doRegisterBeanDefinitions(ele);
}
}
}
else { // 嵌套自定义标签
delegate.parseCustomElement(ele); // !!! 自定义元素
}
}
}
}
else { // 自定义标签
delegate.parseCustomElement(root);
{
String namespaceUri = getNamespaceURI(ele);
// org.springframework.beans.factory.xml.XmlReaderContext.getNamespaceHandlerResolver().resolve(namespaceUri);
// org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(namespaceUri);
// namespaceUri == "http://www.springframework.org/schema/aop"
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); // 获取标签处理器
{
return org.springframework.beans.factory.xml.DefaultNamespaceHandlerResolver.resolve(namespaceUri)
{
Map<String, Object> handlerMappings = getHandlerMappings();// !!! 收集所有jar包中"META-INF/spring.handlers"的命名空间的处理器配置
{
if (this.handlerMappings == null) {
synchronized (this) {
try {
// this.handlerMappingsLocation === "META-INF/spring.handlers"
// http://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
// http://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
// http://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader); // "META-INF/spring.handlers"
if (logger.isDebugEnabled()) {
logger.debug("Loaded NamespaceHandler mappings: " + mappings);
}
Map<String, Object> handlerMappings = new ConcurrentHashMap<String, Object>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", ex);
}
}
}
}
return this.handlerMappings;
}
// namespaceUri == "http://www.springframework.org/schema/aop"
// handlerOrClassName == org.springframework.aop.config.AopNamespaceHandler
Object handlerOrClassName = handlerMappings.get(namespaceUri); // !!! 获取指定命名空间的处理器
// ...
String className = (String) handlerOrClassName;
try {
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass); // 实例化
namespaceHandler.init(); // 处理器进行初始化
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
}
// .....
}
}
if (handler == null) {
error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele);
return null;
}
// handler === org.springframework.aop.config.AopNamespaceHandler 指定命名空间的处理器
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
}
}
postProcessXml(root);
}
}
}
return getRegistry().getBeanDefinitionCount() - countBefore;
}
}
}
finally {
inputStream.close();
}
}
}
}
}
return counter;
}
}
}
return counter;
}
if (actualResources != null) {
for (Resource resource : resources) {
actualResources.add(resource);
}
}
// ...
return loadCount;
}
// ...
}
}
return counter;
}
}
}
}
// ...
}
"META-INF/spring.schemas" 文件的使用
// "META-INF/spring.schemas" 文件的使用
org.springframework.beans.factory.xml.ResourceEntityResolver.resolveEntity()
{
InputSource source = super.resolveEntity(publicId, systemId); // 调用父类的
{
// publicId == null
// systemId == "http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
if (systemId != null) {
if (systemId.endsWith(DTD_SUFFIX)) { // DTD_SUFFIX === ".dtd"
return this.dtdResolver.resolveEntity(publicId, systemId);
}
else if (systemId.endsWith(XSD_SUFFIX)) { // XSD_SUFFIX === ".xsd"
return this.schemaResolver.resolveEntity(publicId, systemId);//!!!
{
return org.springframework.beans.factory.xml.PluggableSchemaResolver.resolveEntity(...)
{
// publicId == null
// systemId == "http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"
if (systemId != null) {
String resourceLocation = getSchemaMappings(){
if (this.schemaMappings == null) {
synchronized (this) {
if (this.schemaMappings == null) {
if (logger.isDebugEnabled()) {
logger.debug("Loading schema mappings from [" + this.schemaMappingsLocation + "]");
}
try {
// 获取类路径上的所有配置
// this.schemaMappingsLocation === "META-INF/spring.schemas"
Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader); // spring-xxxx.jar 包中 "META-INF/spring.schemas"
if (logger.isDebugEnabled()) {
logger.debug("Loaded schema mappings: " + mappings);
}
Map<String, String> schemaMappings = new ConcurrentHashMap<String, String>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
// http\://www.springframework.org/schema/beans/spring-beans-2.0.xsd=org/springframework/beans/factory/xml/spring-beans-2.0.xsd
// http\://www.springframework.org/schema/beans/spring-beans-2.5.xsd=org/springframework/beans/factory/xml/spring-beans-2.5.xsd
// http\://www.springframework.org/schema/beans/spring-beans-3.0.xsd=org/springframework/beans/factory/xml/spring-beans-3.0.xsd
this.schemaMappings = schemaMappings;
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex);
}
}
}
}
return this.schemaMappings;
}.get(systemId);//!!!
if (resourceLocation != null) {
// resourceLocation == "org/springframework/beans/factory/xml/spring-beans-3.0.xsd"
Resource resource = new ClassPathResource(resourceLocation, this.classLoader);
try {
InputSource source = new InputSource(resource.getInputStream());
source.setPublicId(publicId);
source.setSystemId(systemId);
if (logger.isDebugEnabled()) {
logger.debug("Found XML schema [" + systemId + "] in classpath: " + resourceLocation);
}
return source;
}
catch (FileNotFoundException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Couldn't find XML schema [" + systemId + "]: " + resource, ex);
}
}
}
}
return null;
}
}
}
}
return null;
}
if (source == null && systemId != null) {
String resourcePath = null;
try {
String decodedSystemId = URLDecoder.decode(systemId, "UTF-8");
String givenUrl = new URL(decodedSystemId).toString();
String systemRootUrl = new File("").toURI().toURL().toString();
// Try relative to resource base if currently in system root.
if (givenUrl.startsWith(systemRootUrl)) {
resourcePath = givenUrl.substring(systemRootUrl.length());
}
}
catch (Exception ex) {
// ...
}
if (resourcePath != null) {
// ...
Resource resource = this.resourceLoader.getResource(resourcePath);
source = new InputSource(resource.getInputStream());
source.setPublicId(publicId);
source.setSystemId(systemId);
// ...
}
}
return source;
}