spring4.3.6源代码 - core - spring.schemas、spring.handlers的使用

37 篇文章 0 订阅
21 篇文章 0 订阅

 

"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;
}

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值