解析自定義標籤元素java
public BeanDefinition parseCustomElement(Element ele) { return this.parseCustomElement(ele, (BeanDefinition)null); }
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = this.getNamespaceURI(ele); /** *readerContext其實就是咱們的XmlReaderContext *readerContext.getNamespaceHandlerResolver()執行的具體是什麼東西呢? *private final NamespaceHandlerResolver namespaceHandlerResolver;就返回了這個實例變量 * 在XmlReaderContext構造方法進行屬性初始化,咱們繼續查看XmlReaderContext初始化【分支5】 * 這裏看到具體的DefaultNamespaceHandlerResolver * this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri) == DefaultNamespaceHandlerResolver.resolve(namespaceUri); * 這裏獲取了一個NamespaceHandler.具體這個NamespaceHandler是怎麼獲取的暫時不深究,否則進去又出不來了。 * 可是分析下面handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));時又出現了不知所云,就是NamespaceHandler到底實現是什麼?是什麼? *因此不得繼續分析DefaultNamespaceHandlerResolver.resolve(namespaceUri)方法了【分支6】 */ NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if(handler == null) { this.error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } else { return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); } }
//【分支5】在XmlBeanDefinitionReader中有這麼一句代碼 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = this.createBeanDefinitionDocumentReader(); int countBefore = this.getRegistry().getBeanDefinitionCount(); //this.createReaderContext(resource)建立XmlReaderContext documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource)); return this.getRegistry().getBeanDefinitionCount() - countBefore; } //this.createReaderContext(resource)如何建立的呢? 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; } //這裏定義了NamespaceHandlerResolver最終的初始化;代碼跟蹤了半天終於找到具體須要的一個屬性的初始化啦 protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() { //嘿,就是你DefaultNamespaceHandlerResolver return new DefaultNamespaceHandlerResolver(this.getResourceLoader().getClassLoader()); }
//【分支6】DefaultNamespaceHandlerResolver.resolve(namespaceUri) /** * 大概分析了這個類裏面的屬性,咱們看到這裏去加載了一個這麼META-INF/spring.handlers * */ public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver { public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers"; protected final Log logger; private final ClassLoader classLoader; private final String handlerMappingsLocation; private volatile Map<String, Object> handlerMappings; public DefaultNamespaceHandlerResolver() { this((ClassLoader)null, "META-INF/spring.handlers"); } public DefaultNamespaceHandlerResolver(ClassLoader classLoader) { this(classLoader, "META-INF/spring.handlers"); //經過這裏咱們就能夠發現,其實幹了什麼事情?其實就是去讀取spring.handlers配置文件信息去加載一個handlerMappings //爲何這麼作,看看類(DefaultNamespaceHandlerResolver)默認命名空間處理器,這裏就是將咱們xml上面的標籤映射到不一樣的處理器 //原來是這樣,通過分析咱們發現將xml中的aop標籤的處理器變成代碼中的AopNamespaceHandler private Map<String, Object> getHandlerMappings() { if(this.handlerMappings == null) { synchronized(this) { if(this.handlerMappings == null) { try { Properties ex = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader); if(this.logger.isDebugEnabled()) { this.logger.debug("Loaded NamespaceHandler mappings: " + ex); } ConcurrentHashMap handlerMappings = new ConcurrentHashMap(ex.size()); CollectionUtils.mergePropertiesIntoMap(ex, handlerMappings); this.handlerMappings = handlerMappings; } catch (IOException var5) { throw new IllegalStateException("Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", var5); } } } } return this.handlerMappings; } } --- //spring.handlers配置文件信息以下 http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
【注】spring
在這塊代碼出讓我懷疑人生了?app
當new DefaultNamespaceHandlerResolver(this.getResourceLoader().getClassLoader())後咱們看到工具
DefaultNamespaceHandlerResolver這個對象中的測試
private volatile Map<String, Object> handlerMappings
竟然有屬性了?this
觀看構造方法spa
public DefaultNamespaceHandlerResolver(ClassLoader classLoader, String handlerMappingsLocation) { this.logger = LogFactory.getLog(this.getClass()); Assert.notNull(handlerMappingsLocation, "Handler mappings location must not be null"); this.classLoader = classLoader != null?classLoader:ClassUtils.getDefaultClassLoader(); this.handlerMappingsLocation = handlerMappingsLocation; }
其中並無設置handlerMappings屬性值?debug
那到底handlerMappings是何時初始化的呢?【我很暈】調試
通過調試咱們能夠看見handlerMappings屬性信息以下圖所屬code
裏面其實就是加載整個項目
META-INF/spring.handlers
文件其中就包含上圖所示,不少處理器。
-----到底爲何,我還要研究研究----有待補充啊
【通過一晚上思考】
一、當前項目運行環境(IDEA)
二、測試代碼
public class Kid { String name; double height; GregorianCalendar bDay; public Kid () { this.name = "HEAD"; this.height = 1; this.bDay = new GregorianCalendar(1111,1,1); } public Kid (String n, double h, String date) { // method that toString() can't find somehow StringTokenizer st = new StringTokenizer(date, "/", true); this.name = n; this.height = h; } //overriding the toString() method public String toString(){ this.height = 10; System.out.println("toString"+this.height); return name+" "+height+" "+height; } }
測試用例
public class Test { public static void main(String[] args) { Kid kid1 = new Kid("Lexie", 2.6, "11/5/2009"); System.out.println(kid1); } }
1、當在IDEA中配置了這個屬性時
經過調式代碼查看
height就變成10了。而在實例化這個對象的時候咱們給height賦值是2.6。
而在Kid類中咱們看到只有toString方法設置了height=10;
故而咱們能夠分析出
在勾選了全部的class都必須重寫toString()時,IDEA工具在實例化這個對象的時候就隱式調用了toString這個方法。(可是經過斷點又發現沒有執行toString方法,具體爲何會出現這樣我也不知道)
2、當未勾選時
調式結果:
也就是說這個值的變化就跟toString有關係。
進而咱們觀察spring這部分的源代碼
在DefaultNamespaceHandlerResolver類中的toString方法 //他去執行了this.getHandlerMappings() public String toString() { return "NamespaceHandlerResolver using mappings " + this.getHandlerMappings(); } //而getHandlerMappings就是完成spring.handlers的初始化 private Map<String, Object> getHandlerMappings() { if(this.handlerMappings == null) { synchronized(this) { if(this.handlerMappings == null) { try { Properties ex = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader); if(this.logger.isDebugEnabled()) { this.logger.debug("Loaded NamespaceHandler mappings: " + ex); } ConcurrentHashMap handlerMappings = new ConcurrentHashMap(ex.size()); CollectionUtils.mergePropertiesIntoMap(ex, handlerMappings); this.handlerMappings = handlerMappings; } catch (IOException var5) { throw new IllegalStateException("Unable to load NamespaceHandler mappings from location [" + this.handlerMappingsLocation + "]", var5); } } } } return this.handlerMappings; } //也就是說咱們爲何執行完構造方法後,發現 private volatile Map<String, Object> handlerMappings;有值了