Spring IOC容器实现分析

上传人:痛*** 文档编号:193651657 上传时间:2023-03-11 格式:DOCX 页数:73 大小:64.34KB
返回 下载 相关 举报
Spring IOC容器实现分析_第1页
第1页 / 共73页
Spring IOC容器实现分析_第2页
第2页 / 共73页
Spring IOC容器实现分析_第3页
第3页 / 共73页
点击查看更多>>
资源描述
Spring IOC容器实现分析Spring IOC容器实现分析 准备工作 我们都知道,IOC容器和AOP是Spring框架的核心,To the developer, for the developer and by the developer - 简化JAVA企业应用的的开发是Spring框架的目标,为更好的使用IOC容器,我们结 合Spring IOC的源代码对它的实现作一个分析。在了解IOC容器实现的基础上,Spring的使用者可以跟 好的使用IOC容器和Spring框架,同时如果需要对Spring框架作自己的扩展,这些方面的了解也是很有 必要的。我们在这里假设读者已经具备对Spring IOC容器使用的基本知识 - 关于对Spring IOC容器的 使用,可以参考以下的参考资料,这里就不对一些使用和配置的问题多做讲解了。 Spring Framework Reference Guide Spring In Action Expert One-on-one J2EE Development without EJB Professional Java Development with the Spring Framework 还需要准备好Spring的源代码,我们这里用的代码是Spring2.0,当然了一个可以查看源代码的编辑器 也是需要的,这里使用的是Eclipse3.2 - 很多说明性的图例都是直接从屏幕拷贝下来的。下面是一些文 章中用到的专有词汇: 上下文:ApplicationContext Bean定义信息:BeanDefinition Bean工厂:BeanFactory 工厂Bean:FactoryBean 单件:Singleton 概述:基本IOC容器和上下文 因为IOC容器为应用开发者管理对象之间的依赖关系提供了很多便利和基础服务,所以业界有许多IOC 容器供开发者选择,Spring Framework就是其中的一个。对Spring IOC容器的使用来说,我们常常接 触到的Bean工厂和上下文就是IOC容器的表现形式,在这些Spring提供的基本IOC容器的接口定义和 实现的基础上,我们通过定义Bean定义信息来管理应用中的对象依赖关系。 在使用Spring IOC容器的时候,了解Bean工厂和上下文之间的区别对我们了解Spring IOC容器是比 较重要的。从实现上来看,IOC容器定义的基本接口是在Bean工厂定义的,也就是说Bean工厂是 Spring IOC容器的最基本的形式,很显然,BeanFactory只是一个接口类,没有给出IOC容器的实现, 只是对IOC容器需要提供的最基本的服务做了定义,象我们下面看到的 DefaultListableBeanFactory,XmlBeanFactory, ApplicationContext这些都可以看成是IOC容器 的某种具体实现。看看Bean工厂是怎样定义IOC容器的基本服务的: public interface BeanFactory /这里是对工厂Bean的转义定义,因为如果使用bean的名字检索IOC容器得到的对象是工厂Bean 生成的对象, /如果需要得到工厂Bean本身,需要使用转义的名字来向IOC容器检索 String FACTORY_BEAN_PREFIX = &; /这里根据bean的_名字,在IOC容器中得到bean实例,这个IOC容器就象一个大的抽象工厂,用户可 以根据名字得到需要的bean /在Spring中,Bean和普通的JAVA对象不同在于: /Bean已经包含了我们在Bean定义信息中的依赖关系的处理,同时Bean是已经被放到IOC容器中 进行管理了,有它自己的生命周期 Object getBean(String name) throws BeansException; /这里根据bean的名字和Class类型来得到bean实例,和上面的方法不同在于它会抛出异常:如果根 据名字取得的bean实例的Class类型和需要的不同的话。 Object getBean(String name, Class requiredType) throws BeansException; /这里提供对bean的检索,看看是否在IOC容器有这个名字的bean boolean containsBean(String name); /这里根据bean名字得到bean实例,并同时判断这个bean是不是单件,在配置的时候,默认的 Bean被配置成单件形式,如果不需要单件形式,需要用户在Bean定义信息中标注出来,这样IOC容器在 每次接受到用户的getBean要求的时候,会生成一个新的Bean返回给客户使用 - 这就是Prototype形 式 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; /这里对得到bean实例的Class类型 Class getType(String name) throws NoSuchBeanDefinitionException; /这里得到bean的别名,如果根据别名检索,那么其原名也会被检索出来 String getAliases(String name); 这个BeanFactory接口为IOC容器的使用提供了使用规范,在这个基础上,Spring还提供了它符合这个 IOC容器接口的实现供开发人员使用,比如XmlBeanFactory和各种常见的上下文,我们先看一下 XmlBeanFactory这个IOC容器的实现,和那些上下文相比,它提供了基本的IOC容器的基本功能;我们 可以认为直接的BeanFactory的实现是IOC容器的基本形式,而各种上下文的实现是IOC容器的高级表 现形式。XmlBeanFactory的实现是这样的: public class XmlBeanFactory extends DefaultListableBeanFactory /这里为容器定义了一个默认使用的bean定义读取器,在Spring的使用中,Bean定义信息的读取是 容器初始化的一部分,但是在实现上是和容器的注册以及依赖的注入是分开的,这样可以使用灵活的 bean定义读取机制。 private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); /这里需要一个Resource类型的Bean定义信息,实际上的定位过程是由Resource的构建过程来完 成的。 public XmlBeanFactory(Resource resource) throws BeansException this(resource, null); /在初始化函数中使用读取器来对资源进行读取,得到bean定义信息。这里完成整个IOC容器对 Bean定义信息的载入和注册过程 public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); 我们看到XmlBeanFactory使用了DefaultListableBeanFactory作为它持有的IOC容器实现,在这个 基础上,添加了XML形式的Bean定义信息的读取功能。从这个角度看,这个 DefaultListableBeanFactory是很重要的一个Spring IOC实现。下面我们可以看到上下文也和 XmlBeanFactory一样,通过持有这个DefaultListableBeanFactory来获得基本的IOC容器的功能。通 过编程式的使用DefaultListableBeanFactory我们可以看到IOC容器使用的一些基本过程: ClassPathResource res = new ClassPathResource(beans.xml); DefaultListableBeanFactory factory = new DefaultListableBeanFactory; XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(res); 这些代码演示了以下几个步骤: 1. 创建IOC配置文件的抽象资源 2. 创建一个BeanFactory,这里我们使用DefaultListableBeanFactory 3. 创建一个载入bean定义信息的读取器,这里使用XmlBeanDefinitionReader来载入XML形式 的bean定义信息,配置给BeanFactory 4. 从定义好的资源位置读入配置信息,具体的解析过程由XmlBeanDefinitionReader来完成,这 样完成整个载入和注册bean定义的过程。我们的IoC容器就建立起来 这个基本过程我们可以看到,IOC容器建立的基本步骤,这些我们可以编程式的完成这些配置,但在 Spring中,它提供的上下文已经为我们作了这些事情,所以从这个角度说上下文是一个高级形态上的 IOC容器。更方便了用户的使用,相比于那些基本的IOC容器的BeanFactory实现,上下文除了提供基本 的上面看到的容器的基本功能外,还为用户提供了以下的附加服务更方便的让客户使用容器: 可以支持不同的信息源,我们看到ApplicationContext扩展了MessageSource 访问资源, 体现在对ResourceLoader和Resource的支持上面,这样我们可以从不同地方得到 bean定义资源,这样用户程序可以灵活的定义Bean定义信息 支持应用事件,继承了接口ApplicationEventPublisher,这样在上下文中引入了事件机制而 BeanFactory没有 在上下文环境中,这些上下文提供的基础服务更丰富了基本IOC容器的功能。所以一般我们建议客户使 用上下文作为IOC容器来使用 - 和XmlBeanFactory一样,上下文是通过持有 DefaultListableBeanFactory这个基本的IOC容器实现来提供IOC容器的基本功能的,这一点可以在 下面我们分析IOC容器的初始化过程中看得很清楚。 IOC容器和上下文的初始化 简单来说,IOC容器和上下文的初始化包括Bean定义信息的资源定位,载入和注册过程。在上面编程式 的使用DefaultListableBeanFactory中我们可以大致的看到上述过程的实现。值得注意的是,Spring 把这三个过程的完成分开并让不同的模块来完成,这样可以让用户更加灵活的对这三个过程来进行剪 裁,定义出自己最合适的IOC容器的初始化。比如Bean定义信息的资源定位由ResourceLoader通过统 一的Resource接口来完成,这个Resource接口对各种形式的资源信息的使用提供了统一的接口,比如 在文件系统中的Bean定义信息可以使用FileSystemResource,在类路径中可以使用上面看到的 ClassPathResource等等。第二个关键的部分是Bean定义信息的载入,这个载入过程就是把用户定义 好的Bean表示成IOC容器内部的数据结构的过程,在下面我们可以看到这个数据结构就是 BeanDefintion,下面我们会对这个载入的过程做一个详细的分析;第三个过程是向IOC容器注册这些 Bean定义信息的过程,这个过程是通过调用BeanDefinitionRegistry接口的实现来完成的,这个注册 过程把载入过程中解析得到的Bean定义信息向IOC容器中进行注册 - 在IOC容器内部往往使用一个象 HashMap这样的容器来持有这些Bean定义。 值得注意的是,IOC容器和上下文的初始化一般不包含Bean的依赖注入的实现,关于依赖注入实现的过 程在下面也会进行详细的分析。好了,下面我们详细的看一看IOC容器和上下文的Bean定义信息的资源 定位,载入和注册过程是怎么实现的。 Bean定义信息的资源定位 在上面编程式使用DefaultListableBeanFactory的时候,我们可以看到首先定义一个Resource来定位 容器使用的Bean定信息: ClassPathResource res = new ClassPathResource(beans.xml); 这个定义的Resource并不是让DefaultListableBeanFactory直接使用,而是让 BeanDefinitionReader来使用,这里我们也可以看到使用上下文对于直接使用 DefaultListableBeanFactory的好处,因为在上下文中的使用中,Spring已经为我们提供了一系列具 备Resource功能的实现,比如我们常看到的 FileSystemXmlApplicationContext,ClassPathXmlApplicationContext,XmlWebApplicationContext, 我们下面就看看FileSystemXmlApplicationContext是怎样完成这个资源定位过程的,先看看这些类 的继承体系: 可以看到,这个FileSystemXmlApplicationContext已经通过继承具备了ResourceLoader: public class FileSystemXmlApplicationContext extends AbstractXmlApplicationContext /通过这个字符串数组可以持有多个资源位置 private String configLocations; public FileSystemXmlApplicationContext(String configLocation) throws BeansException this(new String configLocation); /这里是一系列初始化函数,得到Resource在文件系统中的位置,并通过refresh来初始化整个IOC 容器 /这个refresh调用时容器的初始化调用入口 public FileSystemXmlApplicationContext(String configLocations) throws BeansException this(configLocations, null); public FileSystemXmlApplicationContext(String configLocations, ApplicationContext parent) throws BeansException super(parent); this.configLocations = configLocations; refresh; public FileSystemXmlApplicationContext(String configLocations, boolean refresh) throws BeansException this(configLocations, refresh, null); public FileSystemXmlApplicationContext(String configLocations, boolean refresh, ApplicationContext parent) throws BeansException super(parent); this.configLocations = configLocations; if (refresh) refresh; protected String getConfigLocations return this.configLocations; /这里是具体的关于在文件系统中定义Bean定义信息的实现 /通过构造一个FileSystemResource来得到一个在文件系统中定义的Bean定义信息 /这个getResourceByPath是在BeanDefinitionReader的loadBeanDefintion中被调用的。 protected Resource getResourceByPath(String path) if (path != null & path.startsWith(/) path = path.substring(1); return new FileSystemResource(path); 从下面的调用关系就可以很清楚的看到在初始化调用的refresh中怎样会触发实际的对资源位置的定位 过程: 大家会比较奇怪,这个FileSystemXmlApplicationContext在什么地方定义了需要的 BeanDefinitionReader呢?我们看看它的基类AbstractRefreshableApplicationContext: public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext /* 这里定义的beanFactory就是ApplicationContext使用的Bean工厂 private DefaultListableBeanFactory beanFactory; . /这个refreshBeanFactory是refresh的一个过程,主要是完成对上下文中IOC容器的初始化 protected final void refreshBeanFactory throws BeansException / Shut down previous bean factory, if any. synchronized (this.beanFactoryMonitor) if (this.beanFactory != null) this.beanFactory.destroySingletons; this.beanFactory = null; / 这里初始化IOC容器 try /这里创建一个DefaultListableBeanFactory作为上下文使用哪个的IOC容器 DefaultListableBeanFactory beanFactory = createBeanFactory; /这里调用BeanDefinitionReader来载入Bean定义信息 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) this.beanFactory = beanFactory; if (logger.isInfoEnabled) logger.info(Bean factory for application context + getDisplayName + : + beanFactory); catch (IOException ex) throw new ApplicationContextException( I/O error parsing XML document for application context + getDisplayName + , ex); /这就是在上下文中创建DefaultListableBeanFactory的地方 protected DefaultListableBeanFactory createBeanFactory return new DefaultListableBeanFactory(getInternalParentBeanFactory); /这里是使用BeanDefinitionReader载入Bean定义的地方,因为允许有多种载入的方式,虽然用得 最多的是XML定义的形式,这里委托给子类完成 protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException, BeansException; 这个loadBeanDefinitios在子类AbstractXmlApplicationContext中的实现: protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException / 这里创建XmlBeanDefinitionReader作为读入器 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); / 这里配置ResourceLoader,因为DefaultResourceLoader是父类,所以this可以直接被使用 beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this); / 这是启动Bean定义信息载入的过程 initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); 从上面的代码可以看到,在初始化FileSystmXmlApplicationContext的过程中,启动了IOC容器的初 始化 - refresh , 这个初始化时通过定义的XmlBeanDefinitionReader来完成的,使用的IOC容器是 DefualtListableBeanFactory,具体的资源载入在XmlBeanDefinitionReader读入Bean定义的时候 实现- 在AbstractBeanDefinitionReader中: public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException /这里取得置入的ResourceLoader,使用的是DefaultResourceLoader ResourceLoader resourceLoader = getResourceLoader; if (resourceLoader = null) throw new BeanDefinitionStoreException( Cannot import bean definitions from location + location + : no ResourceLoader available); if (resourceLoader instanceof ResourcePatternResolver) / 这里对Resource进行解析 try Resource resources = (ResourcePatternResolver) resourceLoader).getResources(location); int loadCount = loadBeanDefinitions(resources); 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 / 这里调用DefaultResourceLoader去取得Resource Resource resource = resourceLoader.getResource(location); int loadCount = loadBeanDefinitions(resource); if (logger.isDebugEnabled) logger.debug(Loaded + loadCount + bean definitions from location + location + ); return loadCount; 具体的取得Resource实现我们可以看看DefaultResourceLoader是怎样完成的: public Resource getResource(String location) Assert.notNull(location, Location must not be null); /这里处理带classpath: 前缀的资源定义,直接返回一个ClassPathResource if (location.startsWith(CLASSPATH_URL_PREFIX) return new ClassPathResource(location.substring(CLASSPATH_URL_PREFIX.length), getClassLoader); else try / 然后使用URLResource URL url = new URL(location); return new UrlResource(url); catch (MalformedURLException ex) / 如果都不能处理交给子类的getResourceByPath,比如我们前面看到的 FileSystemXmlApplicationContext的实现 return getResourceByPath(location); 以上的代码对定位资源的过程做了一个基本的描述,其中涉及到的基本的类有 DefaultResourceLoader这是定位Resource的基本类,由于这个定位过程是在IOC容器的初始化中完 成的,所以我们可以看到一个上下文初始化的基本过程和定义IOC容器,Bean定义读入器的大概过程 - 在FileSystemXmlApplicationContext这一类的XML上下文中使用的是 DefaultListableBeanFactory和XmlBeanDefinitionReader来完成上下文的初始化。 Bean定义信息的载入 上面我们已经看到怎样通过ResourceLoader来定位Bean定义信息的过程,对使用上下文作为IOC容器 的客户来说,这个过程由上下文替客户完成了,对使用B ean工厂的客户来说,需要编程式的为使用的Bean工厂指定Bean定位信息- 而直接的定位过程是与我 们的Bean工厂相关的Bean定义读取器(B eanDefinitionReader)在载入过程中完成的 - 也是IOC容器初始化中载入Bean定义信息过程的一部 分。容器要载入Bean定义信息,当然首先要先能够定位到需要的B ean定义信息了。下面我们看看整个Bean定义信息的载入过程。 对IOC容器来说,这个载入过程相当于把我们定义的Bean定义信息在IOC容器中转化成 BeanDefinition的数据结构并建立映射。以后的IOC容器的对Bean的管理功能和依赖注入功能就是通 过对BeanDefinition进行操作来完成的。这些BeanDefinition数据在IOC容器里通过一个HashMap来 保持和维护 - 这只是一种比较简单的维护方式,如果你觉得需要提高IOC容器的性能和容量,可以自己 做一些扩展。我们看看上面提到的DefaultListableBeanFactory: public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry /* Whether to allow re-registration of a different definition with the same name */ private boolean allowBeanDefinitionOverriding = true; /* 这里对是不是预实例化进行控制*/ private boolean allowEagerClassLoading = true; /* 这里就是存放载入Bean定义信息的地方,以Bean的名字作为key来检索Bean定义信息 */ private final Map beanDefinitionMap = new HashMap; /* 这个列表保存经过排序的Bean的名字 */ private final List beanDefinitionNames = new ArrayList; . 我们看看具体的Bean的载入过程,前面我们看到一个refresh作为载入调用的入口,这里我们也从这里 开始看,在上下文 - AbstractApplicationContext中的实现给出了一个上下文初始化的基本过程: public void refresh throws BeansException, IllegalStateException synchronized (this.startupShutdownMonitor) this.startupTime = System.currentTimeMillis; synchronized (this.activeMonitor) this.active = true; / 这里初始化IOC容器,其中包括了对Bean定义信息的载入 refreshBeanFactory; ConfigurableListableBeanFactory beanFactory = getBeanFactory; / 下面对使用的Bean工厂进行配置,这里使用DefaultListableBeanFactory beanFactory.setBeanClassLoader(getClassLoader); / Populate the bean factory with context-specific resource editors. beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this); / Configure the bean factory with context semantics. beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); / Allows post-processing of the bean factory in context subclasses. postProcessBeanFactory(beanFactory); / 这里对上下文后处理器进行注册 for (Iterator it = getBeanFactoryPostProcessors.iterator; it.hasNext;) BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next; factoryProcessor.postProcessBeanFactory(beanFactory); if (logger.isInfoEnabled) if (getBeanDefinitionCount = 0) logger.info(No beans defined in application context + getDisplayName + ); else logger.info(getBeanDefinitionCount + beans defined in application context + getDisplayName + ); try / 这里对工厂后处理器进行触发 invokeBeanFactoryPostProcessors; / 这里注册Bean的后处理器,因为虽然Bean定义信息被载入了,但是Bean本身并没有被 创建完成。 registerBeanPostProcessors; / Initialize message source for this context. initMessageSource; / Initialize event multicaster for this context. initApplicationEventMulticaster; / Initialize other special beans in specific context subclasses. onRefresh; / Check for listener beans and register them. registerListeners; / 这里对定义为单件的Bean进行预实例化,是否预实例化需要依据Bean定义中的lazyinit 属性的设定 beanFactory.preInstantiateSingletons; / Last step: publish corresponding event. publishEvent(new ContextRefreshedEvent(this); catch (BeansException ex) / Destroy already created singletons to avoid dangling resources. beanFactory.destroySingletons; throw ex; 对Bean定义载入过程,我们可以看看refreshBeanFactory,在 AbstractRefreshableApplicationContext中: protected final void refreshBeanFactory throws BeansException synchronized (this.beanFactoryMonitor) if (this.beanFactory != null) this.beanFactory.destroySingletons; this.beanFactory = null; / 这里是Bean工厂的初始化过程 try /首先创建一个持有的Bean工厂,这里使用的是DefaultListableBeanFactory / 具体的创建过程在上面我们分析过了 DefaultListableBeanFactory beanFactory = createBeanFactory; /这里是调用BeanDefinitionReader载入Bean定义的地方 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) this.beanFactory = beanFactory; if (logger.isInfoEnabled) logger.info(Bean factory for application context + getDisplayName + : + beanFactory); catch (IOException ex) throw new ApplicationContextException( I/O error parsing XML document for application context + getDisplayName + , ex); 具体的载入实现在AbstractXmlApplicationContext中可以看到: protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws IOException / 这里创建XmlBeanDefinitionReader作为Bean定义信息的载入器,同时这个载入器需要一个 Bean工厂的引用,这样可以最后向它注册载入的Bean定义信息 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); / Configure the bean definition reader with this contexts / resource loading environment. beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this); / 这里对载入器进行初始化,并载入Bean定义信息 initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader); 我们看看在XmlBeanDefinitionReader是怎样载入Bean定义信息的,值得注意的是这里已经对定位好 的Resource起作用: 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); try /这里从Resource中取得Bean定义信息的输入流 InputStream inputStream = encodedResource.getResource.getInputStream; try /这里对输入流进行XML解析 InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding != null) inputSource.setEncoding(encodedResource.getEncoding); /这里是实际的解析过程 return doLoadBeanDefinitions(inputSource, encodedResource.getResource); finally inputStream.close; catch (IOException ex) throw new BeanDefinitionStoreException( IOException parsing XML document from + encodedResource.getResource, ex); protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource) throws BeanDefinitionStoreException try int validationMode = getValidationModeForResource(resource); /这里使用DocumentLoader来对XML形式的Bean定义信息进行读入,转换成DOM数据 Document doc = this.documentLoader.loadDocument( inputSource, this.entityResolver, this.errorHandler, validationMode, this.namespaceAware); /得到DOM数据后进行的具体解析和注册工作 return registerBeanDefinitions(doc, resource); . 这个DomcumentReader是一个XML的读入器,被定义为: private DocumentLoader documentLoader = new DefaultDocumentLoader; 作用是解析把XML文档转化为DOM结构信息;我们接着看registerBeanDefinition: public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException / 这里是为了后向版本兼容使用的XML解析器 if (this.parserClass != null) XmlBeanDefinitionParser parser = (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); return parser.registerBeanDefinitions(this, doc, resource); / 这里定义Bean定义信息的解析器,这个解析器根据Spring的Bean定义信息的XML格式和规则 对Bean定义进行解析, / 得到BeanDefinition向IOC容器进行注册 BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader; int countBefore = getBeanFactory.getBeanDefinitionCount; documentReader.registerBeanDefinitions(doc, createReaderContext(resource); return getBeanFactory.getBeanDefinitionCount - countBefore; 这里看到的BeanDefinitionDocumentReader是一个根据Spring的Bean定义规则解析Bean定义的 主要类之一: /这个函数刻画了主要的解析过程 public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) this.readerContext = readerContext; logger.debug(Loading bean definitions); /这里得到Bean定义信息DOM结构的根节点 Element root = doc.getDocumentElement; /这个BeanDefinitionParserDelegate是一个重要的辅助类,它实现了对具体Bean元素在 Bean定义信息的解析 BeanDefinitionParserDelegate delegate = createHelper(readerContext, root); preProcessXml(root); /这是主要的解
展开阅读全文
相关资源
相关搜索

最新文档


当前位置:首页 > 管理文书 > 施工组织


copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!