1. 程式人生 > >Spring原始碼-IOC(三)

Spring原始碼-IOC(三)

Spring原始碼-IOC

springmvc專案啟動入口位置是:web.xml中配置的listener。

在web.xml配置這個監聽器,啟動容器時,就會預設執行它實現的方法。在ContextLoaderListener中關聯了ContextLoader這個類,所以整個載入配置過程由ContextLoader來完成。

//初始化web應用上下文方法:ContextLoader中的initWebApplicationContext方法
public WebApplicationContext initWebApplicationContext(ServletContext servletContext) {
    //判斷web用用根上下文是否已經存在:如果存在則丟擲異常,這麼做是為了防止重複載入
if (servletContext.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE) != null) { throw new IllegalStateException( "Cannot initialize context because there is already a root application context present - " + "check whether you have multiple ContextLoader* definitions in your web.xml!"
); } Log logger = LogFactory.getLog(ContextLoader.class); servletContext.log("Initializing Spring root WebApplicationContext"); if (logger.isInfoEnabled()) { logger.info("Root WebApplicationContext: initialization started"); } long startTime = System.currentTimeMillis(); try
{ // Store context in local instance variable, to guarantee that // it is available on ServletContext shutdown. //在例項屬性變數裡儲存上下文資訊,為了保證在Servlet上下文關閉的時候可以使用 if (this.context == null) { //建立上下文資訊:返回的是:在開發人員沒有配置的情況下返回Context.properties中配置的預設XmlWebApplicationContext物件的例項 this.context = createWebApplicationContext(servletContext); } //判斷獲取到上下文是否為ConfigurableWebApplicationContext的例項(子類的例項:XmlWebApplicationContext) if (this.context instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) this.context; //判斷應用上下文是否已經啟用,如果未啟用:設定父上下文資訊 if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> // determine parent for root web application context, if any. ApplicationContext parent = loadParentContext(servletContext); cwac.setParent(parent); } //重點:配置及重新整理web應用上下文資訊 configureAndRefreshWebApplicationContext(cwac, servletContext); } } //設定根向下文資訊 servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, this.context); //獲取上下文類載入器 ClassLoader ccl = Thread.currentThread().getContextClassLoader(); if (ccl == ContextLoader.class.getClassLoader()) { currentContext = this.context; } else if (ccl != null) { //將類載入器、應用上下文放到ConcurrentHashMap容器中 currentContextPerThread.put(ccl, this.context); } if (logger.isDebugEnabled()) { logger.debug("Published root WebApplicationContext as ServletContext attribute with name [" + WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE + "]"); } if (logger.isInfoEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; logger.info("Root WebApplicationContext: initialization completed in " + elapsedTime + " ms"); } return this.context; } catch (RuntimeException ex) { logger.error("Context initialization failed", ex); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, ex); throw ex; } catch (Error err) { logger.error("Context initialization failed", err); servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, err); throw err; } } //建立應用上下文 protected WebApplicationContext createWebApplicationContext(ServletContext sc) { Class<?> contextClass = determineContextClass(sc); if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Custom context class [" + contextClass.getName() + "] is not of type [" + ConfigurableWebApplicationContext.class.getName() + "]"); } return (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); } //根據配置獲取上下文資訊Class protected Class<?> determineContextClass(ServletContext servletContext) { //判斷是否配置了intitClass String contextClassName = servletContext.getInitParameter(CONTEXT_CLASS_PARAM); if (contextClassName != null) { try { return ClassUtils.forName(contextClassName, ClassUtils.getDefaultClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load custom context class [" + contextClassName + "]", ex); } } else { //預設的:/org/springframework/web/context/ContextLoader.properties中配置的類 contextClassName = defaultStrategies.getProperty(WebApplicationContext.class.getName()); try { return ClassUtils.forName(contextClassName, ContextLoader.class.getClassLoader()); } catch (ClassNotFoundException ex) { throw new ApplicationContextException( "Failed to load default context class [" + contextClassName + "]", ex); } } } //配置及重新整理web應用上下文資訊 protected void configureAndRefreshWebApplicationContext(ConfigurableWebApplicationContext wac, ServletContext sc) { if (ObjectUtils.identityToString(wac).equals(wac.getId())) { // The application context id is still set to its original default value // -> assign a more useful id based on available information String idParam = sc.getInitParameter(CONTEXT_ID_PARAM); if (idParam != null) { wac.setId(idParam); } else { // Generate default id... wac.setId(ConfigurableWebApplicationContext.APPLICATION_CONTEXT_ID_PREFIX + ObjectUtils.getDisplayString(sc.getContextPath())); } } wac.setServletContext(sc); String configLocationParam = sc.getInitParameter(CONFIG_LOCATION_PARAM); if (configLocationParam != null) { wac.setConfigLocation(configLocationParam); } // The wac environment's #initPropertySources will be called in any case when the context // is refreshed; do it eagerly here to ensure servlet property sources are in place for // use in any post-processing or initialization that occurs below prior to #refresh ConfigurableEnvironment env = wac.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment) env).initPropertySources(sc, null); } //定製上下文資訊:初始化類等 customizeContext(sc, wac); //重點:bean註冊入口 wac.refresh(); } //呼叫AbstractApplicationContext類的refresh()方法,XmlWebApplicationContext是它的子類 public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 載入環境配置資訊:配置檔案總的佔位符等資訊初始化 prepareRefresh(); // 獲取beanFactory:返回DefaultListableBeanFactory物件 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 為bean工廠新增:處理器,註冊器,資源資訊註冊等 prepareBeanFactory(beanFactory); try { //允許在上下文子類中對bean工廠進行處理:呼叫XmlWebApplicationContext父類的AbstractRefreshableApplicationContext //postProcessBeanFactory方法,因為方法被AbstractApplicationContext的子類AbstractRefreshableApplicationContext重寫 //為bean工廠繼續新增bean處理器,併為bean工廠註冊beans生命週期及環境資訊 postProcessBeanFactory(beanFactory); //開始執行註冊到該上下文的BeanFactoryPostProcessors invokeBeanFactoryPostProcessors(beanFactory); // 開始註冊BeanPostProcessor來攔截其他的bean的初始化過程 registerBeanPostProcessors(beanFactory); // 初始化訊息源 initMessageSource(); //註冊上下文事件的廣播集 initApplicationEventMulticaster(); //初始化一些特殊的bean onRefresh(); //查詢並校驗監聽器並註冊 registerListeners(); // 解析並建立Class物件所有非懶載入的所有bean finishBeanFactoryInitialization(beanFactory); //最後一步釋出所有的運用 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); } } } //獲取beanFactory方法 protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //重新整理beanFactory:銷燬已經存在的bean資訊,關閉已經存在的工廠 //同時開始解析並建立Class物件bean並註冊到應用上下文中 refreshBeanFactory();//重點的重點 //建立新的工廠:DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; } //呼叫XmlWebApplicationContext父類AbstractRefreshableApplicationContext的refreshBeanFactory方法 @Override protected final void refreshBeanFactory() throws BeansException { //銷燬已經存在的bean資訊,關閉已經存在的工廠 if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); //定製bean工廠:允許bean定義過載,允許迴圈引用 customizeBeanFactory(beanFactory); //載入定義的bean資訊:呼叫子類XmlWebApplicationContext中的實現loadBeanDefinitions loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } } //XmlWebApplicationContext:開始解析並建立Class物件bean並註冊到應用上下文中 protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //通過beanFactory建立XmlBeanDefinitionReader讀取器 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. beanDefinitionReader.setEnvironment(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. //初始化bean定義讀取器:空實現 initBeanDefinitionReader(beanDefinitionReader); // loadBeanDefinitions(beanDefinitionReader); } //XmlWebApplicationContext:loadBeanDefinitions(reader) protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws IOException { String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { //XmlBeanDefinitionReader的AbstractBeanDefinitionReader父類的loadBeanDefinitions reader.loadBeanDefinitions(configLocation); } } } //AbstractBeanDefinitionReader父類的loadBeanDefinitions public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException { return loadBeanDefinitions(location, null); } //AbstractBeanDefinitionReader父類的過載方法loadBeanDefinitions:載入配置檔案資訊 public int loadBeanDefinitions(String location, Set<Resource> actualResources) throws BeanDefinitionStoreException { ResourceLoader resourceLoader = getResourceLoader(); if (resourceLoader == null) { throw new BeanDefinitionStoreException( "Cannot import bean definitions from location [" + location + "]: no ResourceLoader available"); } if (resourceLoader instanceof ResourcePatternResolver) { // Resource pattern matching available. try { //多個配置檔案載入 Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location); //呼叫AbstractBeanDefinitionReader的loadBeanDefinitions(resources); int loadCount = loadBeanDefinitions(resources); if (actualResources != null) { for (Resource resource : resources) { actualResources.add(resource); } } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location pattern [" + location + "]"); } return loadCount; } catch (IOException ex) { throw new BeanDefinitionStoreException( "Could not resolve bean definition resource pattern [" + location + "]", ex); } } else { // Can only load single resources by absolute URL. //單個配置檔案載入 Resource resource = resourceLoader.getResource(location); //呼叫XmlBeanDefinitionReader實現BeanDefinitionReader(AbstractBeanDefinitionReader實現了該介面)介面中的loadBeanDefinitions int loadCount = loadBeanDefinitions(resource); if (actualResources != null) { actualResources.add(resource); } if (logger.isDebugEnabled()) { logger.debug("Loaded " + loadCount + " bean definitions from location [" + location + "]"); } return loadCount; } } //呼叫AbstractBeanDefinitionReader的loadBeanDefinitions(resources); public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException { Assert.notNull(resources, "Resource array must not be null"); int counter = 0; for (Resource resource : resources) { //迴圈//呼叫XmlBeanDefinitionReader實現BeanDefinitionReader(AbstractBeanDefinitionReader實現了該介面)介面中的loadBeanDefinitions counter += loadBeanDefinitions(resource); } return counter; } //XmlBeanDefinitionReader的loadBeanDefinitions(resource); public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException { return loadBeanDefinitions(new EncodedResource(resource)); } //XmlBeanDefinitionReader中的過載方法的loadBeanDefinitions public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException { Assert.notNull(encodedResource, "EncodedResource must not be null"); if (logger.isInfoEnabled()) { logger.info("Loading XML bean definitions from " + encodedResource.getResource()); } Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get(); if (currentResources == null) { currentResources = new HashSet<EncodedResource>(4); this.resourcesCurrentlyBeingLoaded.set(currentResources); } if (!currentResources.add(encodedResource)) { throw new BeanDefinitionStoreException( "Detected cyclic loading of " + encodedResource + " - check your import definitions!"); } try { InputStream inputStream = encodedResource.getResource().getInputStream(); try { InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } //開始載入bean定義資訊 return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); } finally { inputStream.close(); } } catch (IOException ex) { throw new BeanDefinitionStoreException( "IOException parsing XML document from " + encodedResource.getResource(), ex); } finally { currentResources.remove(encodedResource); if (currentResources.isEmpty()) { this.resourcesCurrentlyBeingLoaded.remove(); } } } //載入bean定義資訊 protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException { try { //獲取配置檔案的文件物件 Document doc = doLoadDocument(inputSource, resource); //註冊bean定義資訊:重點 return registerBeanDefinitions(doc, resource); } catch (BeanDefinitionStoreException ex) { throw ex; } catch (SAXParseException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex); } catch (SAXException ex) { throw new XmlBeanDefinitionStoreException(resource.getDescription(), "XML document from " + resource + " is invalid", ex); } catch (ParserConfigurationException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Parser configuration exception parsing XML from " + resource, ex); } catch (IOException ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "IOException parsing XML document from " + resource, ex); } catch (Throwable ex) { throw new BeanDefinitionStoreException(resource.getDescription(), "Unexpected exception parsing XML document from " + resource, ex); } } //註冊bean定義資訊:重點 public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException { BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader(); int countBefore = getRegistry().getBeanDefinitionCount(); //通過文件讀取器開始讀取並註冊bean資訊 documentReader.registerBeanDefinitions(doc, createReaderContext(resource)); return getRegistry().getBeanDefinitionCount() - countBefore; } //BeanDefinitionDocumentReader的子類DefaultBeanDefinitionDocumentReader的registerBeanDefinitions方法 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) { this.readerContext = readerContext; logger.debug("Loading bean definitions"); //獲取根元素資訊 Element root = doc.getDocumentElement(); //註冊bean定義資訊 doRegisterBeanDefinitions(root); } //DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法 protected void doRegisterBeanDefinitions(Element root) { //獲取父級bean定義解析代理 BeanDefinitionParserDelegate parent = this.delegate; this.delegate = createDelegate(getReaderContext(), root, parent); if (this.delegate.isDefaultNamespace(root)) { String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE); if (StringUtils.hasText(profileSpec)) { String[] specifiedProfiles = StringUtils.tokenizeToStringArray( profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS); if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) { if (logger.isInfoEnabled()) { logger.info("Skipped XML bean definition file due to specified profiles [" + profileSpec + "] not matching: " + getReaderContext().getResource()); } return; } } } //xml預處理:空實現 preProcessXml(root); //解析bean定義資訊 parseBeanDefinitions(root, this.delegate); postProcessXml(root); this.delegate = parent; } /** * 開始解析bean定義資訊:DefaultBeanDefinitionDocumentReader的方法 * Parse the elements at the root level in the document: * "import", "alias", "bean". * @param root the DOM root element of the document */ protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { //判斷是否是beans空間 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)) { //解析:beans下的import,alias,bean,beans元素 parseDefaultElement(ele, delegate); } else { //其他名稱空間下的子標籤解析:context:component-scan等 delegate.parseCustomElement(ele); } } } } else { //其他名稱空間下的子標籤解析:context:component-scan等 delegate.parseCustomElement(root); } } //===============================================================非註解bean解析過程開始========================================================= //xml配置類資訊解析:開始解析bean定義資訊:DefaultBeanDefinitionDocumentReader的parseDefaultElement方法 private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) { if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) { //解析import標籤 importBeanDefinitionResource(ele); } else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) { //解析import標籤 processAliasRegistration(ele); } else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) { //解析bean標籤 processBeanDefinition(ele, delegate); } else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) { //解析巢狀的beans標籤 doRegisterBeanDefinitions(ele); } } //非註解:解析bean標籤 protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //獲取bean定義資訊 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { //裝飾bean定義資訊 bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder); try { // 註冊bean BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } catch (BeanDefinitionStoreException ex) { getReaderContext().error("Failed to register bean definition with name '" + bdHolder.getBeanName() + "'", ele, ex); } // Send registration event. getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder)); } } //bean定義解析:BeanDefinitionParserDelegate的parseBeanDefinitionElement方法 public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { //獲取bean id 屬性 String id = ele.getAttribute(ID_ATTRIBUTE); //獲取bean name 屬性 String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); List<String> aliases = new ArrayList<String>(); if (StringUtils.hasLength(nameAttr)) { String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS); aliases.addAll(Arrays.asList(nameArr)); } String beanName = id; //如果bean id和name屬性均為空,則列印日誌 if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) { beanName = aliases.remove(0); if (logger.isDebugEnabled()) { logger.debug("No XML 'id' specified - using '" + beanName + "' as bean name and " + aliases + " as aliases"); } } //校驗bean id是否唯一,如果不存在則放入usedNames的set集合,否則報錯 if (containingBean == null) { checkNameUniqueness(beanName, aliases, ele); } //解析bean的其他屬性 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean); if (beanDefinition != null) { if (!StringUtils.hasText(beanName)) { try { if (containingBean != null) { beanName = BeanDefinitionReaderUtils.generateBeanName( beanDefinition, this.readerContext.getRegistry(), true); } else { beanName = this.readerContext.generateBeanName(beanDefinition); // Register an alias for the plain bean class name, if still possible, // if the generator returned the class name plus a suffix. // This is expected for Spring 1.2/2.0 backwards compatibility. String beanClassName = beanDefinition.getBeanClassName(); if (beanClassName != null && beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() && !this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) { aliases.add(beanClassName); } } if (logger.isDebugEnabled()) { logger.debug("Neither XML 'id' nor 'name' specified - " + "using generated bean name [" + beanName + "]"); } } catch (Exception ex) { error(ex.getMessage(), ele); return null; } } String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; } //非註解bean解析:解析其他屬性 public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { //將包含beanName屬性的物件放到解析狀態的棧中:Stack this.parseState.push(new BeanEntry(beanName)); String className = null; //判斷當前bean是否包含class屬性 if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { String parent = null; //判斷當前bean是否包含parent屬性 if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); } AbstractBeanDefinition bd = createBeanDefinition(className, parent); //解析bean定義的其他屬性:singleton,scope,abstract,autowire等 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //解析bean的description屬性 bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT)); //解析bean的meta元素 parseMetaElements(ele, bd); //解析bean的lookup-method屬性:方法返回動態載入:特殊的注入方式,很少用到 parseLookupOverrideSubElements(ele, bd.getMethodOverrides()); //解析bean的replaced-method屬性:可以在執行時用新的方法替換舊的方法,很少用到 parseReplacedMethodSubElements(ele, bd.getMethodOverrides()); //解析bean的constructor-arg子元素 parseConstructorArgElements(ele, bd); //解析property子元素 parsePropertyElements(ele, bd); //解析qualifier子元素 parseQualifierElements(ele, bd); bd.setResource(this.readerContext.getResource()); bd.setSource(extractSource(ele)); return bd; } catch (ClassNotFoundException ex) { error("Bean class [" + className + "] not found", ele, ex); } catch (NoClassDefFoundError err) { error("Class that bean class [" + className + "] depends on not found", ele, err); } catch (Throwable ex) { error("Unexpected failure during bean definition parsing", ele, ex); } finally { this.parseState.pop(); } return null; } /** * 根據bean的className和parentName建立一個封裝了bean class和parent的BeanDefinition物件 * Create a bean definition for the given class name and parent name. * @param className the name of the bean class * @param parentName the name of the bean's parent bean * @return the newly created bean definition * @throws ClassNotFoundException if bean class resolution was attempted but failed */ protected AbstractBeanDefinition createBeanDefinition(String className, String parentName) throws ClassNotFoundException { return BeanDefinitionReaderUtils.createBeanDefinition( parentName, className, this.readerContext.getBeanClassLoader()); } // public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition(); bd.setParentName(parentName); if (className != null) { //累載入器不為空:使用者自定義類載入器不為空 if (classLoader != null) { //spring的反射工具獲取className對應類的的Class物件 bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { //類載入器為空,說明是(bootstrap:對開發人員遮蔽)根載入器,底層有處理,String物件 bd.setBeanClassName(className); } } return bd; } //===============================================================非註解bean解析過程完畢========================================================= //===============================================================非註解bean註冊過程開始========================================================= //BeanDefinitionReaderUtils的靜態方法registerBeanDefinition public static void registerBeanDefinition( BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { // Register bean definition under primary name. String beanName = definitionHolder.getBeanName(); registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); // Register aliases for bean name, if any. String[] aliases = definitionHolder.getAliases(); if (aliases != null) { for (String alias : aliases) { registry.registerAlias(beanName, alias); } } } //--------------------------------------------------------------------- // Implementation of BeanDefinitionRegistry interface //----------------------------------BeanDefinitionRegistry的子類DefaultListableBeanFactory ----------------------------------- ///** Map of bean definition objects, keyed by bean name */ //private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition oldBeanDefinition; //根據當前beanName檢視是否已經註冊 oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { //如果bean不允許過載 if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } //如果沒有異常,則用覆蓋老的beanDefainition(concurrentHashMap的key相同則覆蓋) this.beanDefinitionMap.put(beanName, beanDefinition); } else { //還沒有註冊,新增到快取集合中 //已經開始建立 if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) //給bean定義物件儲存結合新增上鎖,防止多執行緒操作 synchronized (this.beanDefinitionMap) { //將bean定義資訊存到物件的concurrentHashMap集合中 this.beanDefinitionMap.put(beanName, beanDefinition); //Copy on Write 設計模式,既讀寫分離思想,先建立一個新的集合,然後把原來的集合放到新的裡,老的集合不影響讀取操作,然後再將老的集合的引用指向新的引用 List<String> updatedDefinitions = new ArrayList<String>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; if (this.manualSingletonNames.contains(beanName)) { //同樣的設計思想:在java的concurrent併發包下有對應的集合設計 Set<String> updatedSingletons = new LinkedHashSet<String>(this.manualSingletonNames); updatedSingletons.remove(beanName); this.manualSingletonNames = updatedSingletons; } } } else { // Still in startup registration phase //仍舊在啟動註冊階段 this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); this.manualSingletonNames.remove(beanName); } this.frozenBeanDefinitionNames = null; } if (oldBeanDefinition != null || containsSingleton(beanName)) { //如果已經存在,銷燬當前bean相關的資訊 resetBeanDefinition(beanName); } } //===============================================================非註解bean註冊過程結束========================================================= //================================================================註解類bean的解析並建立Class物件過程開始==================================================== //BeanDefinitionParserDelegate的parseCustomElement方法 public BeanDefinition parseCustomElement(Element ele) { return parseCustomElement(ele, null); } //BeanDefinitionParserDelegate的過載方法parseCustomElement public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { //根據名稱空間回去對應名稱空間的處理器:例如context名稱空間的處理器為ContextNamespaceHandler String namespaceUri = getNamespaceURI(ele); NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } //呼叫名稱空間的處理器方法進行解析,返回bean定義資訊 return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); } //ContextNamespaceHandler的父類NamespaceHandlerSupport的parse方法 public class ContextNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { //註冊各種bean定義解析器 registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser()); registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser()); registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser()); registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser()); registerBeanDefinitionParser("load-time-weaver",