📄 defaultnamespacehandlerresolver.java
字号:
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.beans.factory.xml;
import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* Default implementation of the {@link NamespaceHandler} interface.
* Resolves namespace URIs to implementation classes based on the mappings
* contained in mapping file.
*
* <p>By default, this implementation looks for the mapping file at
* <code>META-INF/spring.handlers</code>, but this can be changed using the
* {@link #DefaultNamespaceHandlerResolver(ClassLoader, String)} constructor.
*
* @author Rob Harrop
* @author Juergen Hoeller
* @since 2.0
* @see NamespaceHandler
* @see DefaultBeanDefinitionDocumentReader
*/
public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {
/**
* The location to look for the mapping files. Can be present in multiple JAR files.
*/
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";
/** Logger available to subclasses */
protected final Log logger = LogFactory.getLog(getClass());
/** Stores the mappings from namespace URI Strings to NamespaceHandler instances */
private Map handlerMappings;
/**
* Create a new <code>DefaultNamespaceHandlerResolver</code> using the
* default mapping file location.
* <p>This constructor will result in the thread context ClassLoader being used
* to load resources.
* @see #DEFAULT_HANDLER_MAPPINGS_LOCATION
*/
public DefaultNamespaceHandlerResolver() {
this(null, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
/**
* Create a new <code>DefaultNamespaceHandlerResolver</code> using the
* default mapping file location.
* @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be <code>null</code>, in
* which case the thread context ClassLoader will be used)
* @see #DEFAULT_HANDLER_MAPPINGS_LOCATION
*/
public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);
}
/**
* Create a new <code>DefaultNamespaceHandlerResolver</code> using the
* supplied mapping file location.
* @param classLoader the {@link ClassLoader} instance used to load mapping resources (may be <code>null</code>, in
* which case the thread context ClassLoader will be used)
* @param handlerMappingsLocation the mapping file location
*/
public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) {
Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null");
ClassLoader classLoaderToUse = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
initHandlerMappings(classLoaderToUse, handlerMappingsLocation);
}
/**
* Load the namespace URI -> <code>NamespaceHandler</code> class mappings from the configured
* mapping file. Converts the class names into actual class instances and checks that
* they implement the <code>NamespaceHandler</code> interface. Pre-instantiates an instance
* of each <code>NamespaceHandler</code> and maps that instance to the corresponding
* namespace URI.
*/
private void initHandlerMappings(ClassLoader classLoader, String handlerMappingsLocation) {
Properties mappings = loadMappings(classLoader, handlerMappingsLocation);
if (logger.isDebugEnabled()) {
logger.debug("Loaded mappings [" + mappings + "]");
}
this.handlerMappings = new HashMap(mappings.size());
for (Enumeration en = mappings.propertyNames(); en.hasMoreElements();) {
String namespaceUri = (String) en.nextElement();
String className = mappings.getProperty(namespaceUri);
try {
Class handlerClass = ClassUtils.forName(className, classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new IllegalArgumentException("Class [" + className +
"] does not implement the NamespaceHandler interface");
}
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
namespaceHandler.init();
this.handlerMappings.put(namespaceUri, namespaceHandler);
}
catch (ClassNotFoundException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Ignoring namespace handler [" + className + "]: handler class not found", ex);
}
}
catch (LinkageError err) {
if (logger.isWarnEnabled()) {
logger.warn("Ignoring namespace handler [" + className +
"]: problem with handler class file or dependent class", err);
}
}
}
}
private Properties loadMappings(ClassLoader classLoader, String handlerMappingsLocation) {
try {
return PropertiesLoaderUtils.loadAllProperties(handlerMappingsLocation, classLoader);
}
catch (IOException ex) {
throw new IllegalStateException(
"Unable to load NamespaceHandler mappings from location [" +
handlerMappingsLocation + "]. Root cause: " + ex);
}
}
/**
* Locate the {@link NamespaceHandler} for the supplied namespace URI
* from the configured mappings.
* @param namespaceUri the relevant namespace URI
* @return the located {@link NamespaceHandler}, or <code>null</code> if none found
*/
public NamespaceHandler resolve(String namespaceUri) {
return (NamespaceHandler) this.handlerMappings.get(namespaceUri);
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -