Spring如何通過定義在META-INF/spring.handlers中的屬性進行配置檔案解析
阿新 • • 發佈:2018-12-30
毫無疑問這些東西肯定在Spring的入口函式refresh()之中進行的。
AbstractApplicationContext
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();//獲得一個新的beanFactory,並進行一些相關的load
AbstractRefreshableApplicationContextprotected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory();//通知子類context重新整理內部的BeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }
protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans();//銷燬當前context管理的所有bean closeBeanFactory();//關閉beanFactory } try {//建立一個新的beanFactory(DefaultListableBeanFactory) DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory);//載入BeanDefinition synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } //... }
XmlWebApplicationContext
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. //建立一個新的XmlBeanDefinitionReader 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);//接著載入BeanDefinition }
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException {
String[] configLocations = getConfigLocations();//獲得ServletConfig的配置檔案位置
if (configLocations != null) {
for (String configLocation : configLocations) {
reader.loadBeanDefinitions(configLocation);//根據位置載入BeanDefinition
}
}
}
中間省略
XmlBeanDefinitionReader
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
documentReader.setEnvironment(this.getEnvironment());
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));//建立一個ReaderContext,
//註冊BeanDefinition
return getRegistry().getBeanDefinitionCount() - countBefore;
}
protected XmlReaderContext createReaderContext(Resource resource) {
if (this.namespaceHandlerResolver == null) {//建立預設的名稱控制元件處理器解析器
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}//返回建立好的xmlReaderContext,將建立好的namespaceHandlerResolver傳入
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, this.namespaceHandlerResolver);
}
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {//對應的NamespaceHandlerResolver
return new DefaultNamespaceHandlerResolver(getResourceLoader().getClassLoader());
}
public DefaultNamespaceHandlerResolver(ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION);//這個位置就在META-INF/spring.handlers
}
接著往下走註冊BeanDefinitioni的過程
DefaultBeanDefinitionDocumentReader
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
logger.debug("Loading bean definitions");
Element root = doc.getDocumentElement();
doRegisterBeanDefinitions(root);//註冊beanDefinition 將root根節點傳入
}
protected void doRegisterBeanDefinitions(Element root) {
//....
this.delegate = createDelegate(this.readerContext, root, parent);//建立一個委託
preProcessXml(root);
parseBeanDefinitions(root, this.delegate);//處理
postProcessXml(root);
this.delegate = parent;
}
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);
}
}
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) {//null
String namespaceUri = getNamespaceURI(ele);//根據之前設定的解析器對這個uri進行解析,獲得一個NamespaceHandler
//通過鍵值對的形式存在檔案裡面,在resolve裡面對類名獲取,然後例項化一個handler物件
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
//....現在可以對配置檔案進行解析了。
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
DefaultNamespaceHandlerResolver public NamespaceHandler resolve(String namespaceUri) {
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);//獲取處理器的類名
if (handlerOrClassName == null) {
return null;
}
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
else {
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);//快取這個handler,下次其他的可以再次利用
return namespaceHandler;
}
//....
}
}