`
pp397443687
  • 浏览: 3924 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

XmlBeanFactory

阅读更多
   1. public class XmlBeanFactory extends DefaultListableBeanFactory {
   2.

   3.     private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);
   4.

   5.


   6.    
   7.     public XmlBeanFactory(Resource resource) throws BeansException {
   8.         this(resource, null);
   9.     }
  10.

  11.


  12.     public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException {
  13.         super(parentBeanFactory);
  14.         this.reader.loadBeanDefinitions(resource);
  15.     }
  16.

  17. }
  18.

从reader.loadBeanDefinitions(resource);可见,从外部加载xml配置文件,XmlBeanFactory是通过委托给XmlBeanDefinitionReader做的,其他都是DefaultListableBeanFactory 继承而来;

那么,我们重点来分析一些xml文件是如何把配置加载到BeanFactory中的:
   1.     public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException {
   2.         XmlBeanDefinitionParser parser =
   3.                 (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass);
   4.         return parser.registerBeanDefinitions(this, doc, resource);
   5.     }

registerBeanDefinitions是reader是通过SAXBuilder把外部xml转换成为了Document,然后用BeanDefinition解析器来解析这个documeng文档;

   1. public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource)
   2.             throws BeanDefinitionStoreException {
   3.

   4.         this.beanDefinitionReader = reader;
   5.         this.resource = resource;
   6.

   7.         logger.debug("Loading bean definitions");
   8.         Element root = doc.getDocumentElement();
   9.

  10.         initDefaults(root);
  11.         if (logger.isDebugEnabled()) {
  12.             logger.debug("Default lazy init '" + getDefaultLazyInit() + "'");
  13.             logger.debug("Default autowire '" + getDefaultAutowire() + "'");
  14.             logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'");
  15.         }
  16.

  17.         preProcessXml(root);
  18.         int beanDefinitionCount = parseBeanDefinitions(root);
  19.         if (logger.isDebugEnabled()) {
  20.             logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource);
  21.         }
  22.         postProcessXml(root);
  23.

  24.         return beanDefinitionCount;
  25.     }

registerBeanDefinitions方法从root元素开始处理整个document,在这里我们可以在一次看见spring给我们留出来的钩子方法,典型的模板方法的应用;

preProcessXml(root){};

postProcessXml(root){};



   1. protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {
   2.         NodeList nl = root.getChildNodes();
   3.         int beanDefinitionCount = 0;
   4.         for (int i = 0; i < nl.getLength(); i++) {
   5.             Node node = nl.item(i);
   6.             if (node instanceof Element) {
   7.                 Element ele = (Element) node;
   8.                 if (IMPORT_ELEMENT.equals(node.getNodeName())) {
   9.                     importBeanDefinitionResource(ele);
  10.                 }
  11.                 else if (ALIAS_ELEMENT.equals(node.getNodeName())) {
  12.                     String name = ele.getAttribute(NAME_ATTRIBUTE);
  13.                     String alias = ele.getAttribute(ALIAS_ATTRIBUTE);
  14.                     this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias);
  15.                 }
  16.                 else if (BEAN_ELEMENT.equals(node.getNodeName())) {
  17.                     beanDefinitionCount++;
  18.                     BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false);
  19.                     BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory());
  20.                 }
  21.             }
  22.         }
  23.         return beanDefinitionCount;
  24.     }

parseBeanDefinitions方法中,我们开始遍历整个文档的节点,处理每个节点;并且从节点的名字,我们可以判断出三种节点,一种是<import>一种是<alias>一种是<bean>
BeanDefinitionHolder 是一个含有BeanDefinition和Bean name的存储器,我们主要来看一下spring如何从bean element 构造出BeanDefinition();



   1. protected BeanDefinitionHolder parseBeanDefinitionElement(Element ele, boolean isInnerBean)
   2.             throws BeanDefinitionStoreException {
   3.
   4.         String id = ele.getAttribute(ID_ATTRIBUTE);
   5.         String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
   6.
   7.         List aliases = new ArrayList();
   8.         if (StringUtils.hasLength(nameAttr)) {
   9.             String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS);
  10.             aliases.addAll(Arrays.asList(nameArr));
  11.         }
  12.
  13.         String beanName = id;
  14.         if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
  15.             beanName = (String) aliases.remove(0);
  16.             if (logger.isDebugEnabled()) {
  17.                 logger.debug("No XML 'id' specified - using '" + beanName +
  18.                         "' as bean name and " + aliases + " as aliases");
  19.             }
  20.         }
  21.
  22.         BeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName);
  23.
  24.         if (!StringUtils.hasText(beanName) && beanDefinition instanceof AbstractBeanDefinition) {
  25.             beanName = BeanDefinitionReaderUtils.generateBeanName(
  26.                     (AbstractBeanDefinition) beanDefinition, this.beanDefinitionReader.getBeanFactory(), isInnerBean);
  27.             if (logger.isDebugEnabled()) {
  28.                 logger.debug("Neither XML 'id' nor 'name' specified - " +
  29.                         "using generated bean name [" + beanName + "]");
  30.             }
  31.         }
  32.
  33.         String[] aliasesArray = StringUtils.toStringArray(aliases);
  34.         return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
  35.     }


主要是获取alias,把名字用.;分开,解析成为别名;

   1.


   2.



   3. protected BeanDefinition parseBeanDefinitionElement(Element ele, String beanName)
   4.             throws BeanDefinitionStoreException {
   5.
   6.         String className = null;
   7.         if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
   8.             className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
   9.         }
  10.         String parent = null;
  11.         if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
  12.             parent = ele.getAttribute(PARENT_ATTRIBUTE);
  13.         }
  14.
  15.         try {
  16.             ConstructorArgumentValues cargs = parseConstructorArgElements(ele, beanName);
  17.             MutablePropertyValues pvs = parsePropertyElements(ele, beanName);
  18.
  19.             AbstractBeanDefinition bd = BeanDefinitionReaderUtils.createBeanDefinition(
  20.                     className, parent, cargs, pvs, getBeanDefinitionReader().getBeanClassLoader());
  21.
  22.             if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
  23.                 String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
  24.                 bd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS));
  25.             }
  26.
  27.             if (ele.hasAttribute(FACTORY_METHOD_ATTRIBUTE)) {
  28.                 bd.setFactoryMethodName(ele.getAttribute(FACTORY_METHOD_ATTRIBUTE));
  29.             }
  30.             if (ele.hasAttribute(FACTORY_BEAN_ATTRIBUTE)) {
  31.                 bd.setFactoryBeanName(ele.getAttribute(FACTORY_BEAN_ATTRIBUTE));
  32.             }
  33.
  34.             String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
  35.             if (DEFAULT_VALUE.equals(dependencyCheck)) {
  36.                 dependencyCheck = getDefaultDependencyCheck();
  37.             }
  38.             bd.setDependencyCheck(getDependencyCheck(dependencyCheck));
  39.
  40.             String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
  41.             if (DEFAULT_VALUE.equals(autowire)) {
  42.                 autowire = getDefaultAutowire();
  43.             }
  44.             bd.setAutowireMode(getAutowireMode(autowire));
  45.
  46.             if (ele.hasAttribute(INIT_METHOD_ATTRIBUTE)) {
  47.                 String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
  48.                 if (!"".equals(initMethodName)) {
  49.                     bd.setInitMethodName(initMethodName);
  50.                 }
  51.             }
  52.             else {
  53.                 if (getDefaultInitMethod() != null) {
  54.                     bd.setInitMethodName(getDefaultInitMethod());
  55.                     bd.setEnforceInitMethod(false);
  56.                 }
  57.             }
  58.
  59.             if (ele.hasAttribute(DESTROY_METHOD_ATTRIBUTE)) {
  60.                 String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
  61.                 if (!"".equals(destroyMethodName)) {
  62.                     bd.setDestroyMethodName(destroyMethodName);
  63.                 }
  64.             }
  65.             else {
  66.                 if (getDefaultDestroyMethod() != null) {
  67.                     bd.setDestroyMethodName(getDefaultDestroyMethod());
  68.                     bd.setEnforceDestroyMethod(false);
  69.                 }
  70.             }
  71.
  72.             parseLookupOverrideSubElements(ele, beanName, bd.getMethodOverrides());
  73.             parseReplacedMethodSubElements(ele, beanName, bd.getMethodOverrides());
  74.
  75.             bd.setResourceDescription(getResource().getDescription());
  76.
  77.             if (ele.hasAttribute(ABSTRACT_ATTRIBUTE)) {
  78.                 bd.setAbstract(TRUE_VALUE.equals(ele.getAttribute(ABSTRACT_ATTRIBUTE)));
  79.             }
  80.
  81.             if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
  82.                 bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
  83.             }
  84.
  85.             String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
  86.             if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
  87.                 // Just apply default to singletons, as lazy-init has no meaning for prototypes.
  88.                 lazyInit = getDefaultLazyInit();
  89.             }
  90.             bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
  91.
  92.             return bd;
  93.         }
  94.
  95.         catch (BeanDefinitionStoreException ex) {
  96.             throw ex;
  97.         }
  98.         catch (ClassNotFoundException ex) {
  99.             throw new BeanDefinitionStoreException(
100.                     getResource(), beanName, "Bean class [" + className + "] not found", ex);
101.         }
102.         catch (NoClassDefFoundError err) {
103.             throw new BeanDefinitionStoreException(
104.                     getResource(), beanName, "Class that bean class [" + className + "] depends on not found", err);
105.         }
106.         catch (Throwable ex) {
107.             throw new BeanDefinitionStoreException(
108.                     getResource(), beanName, "Unexpected failure during bean definition parsing", ex);
109.         }
110.     }
111.
112.   

上述代码详细的解析了各种元素,并且把他set到BeanDefinition中去;

最后:

   1. public static void registerBeanDefinition(
   2.             BeanDefinitionHolder bdHolder, BeanDefinitionRegistry beanFactory) throws BeanDefinitionStoreException {
   3.
   4.         // Register bean definition under primary name.
   5.         beanFactory.registerBeanDefinition(bdHolder.getBeanName(), bdHolder.getBeanDefinition());
   6.
   7.         // Register aliases for bean name, if any.
   8.         if (bdHolder.getAliases() != null) {
   9.             for (int i = 0; i < bdHolder.getAliases().length; i++) {
  10.                 beanFactory.registerAlias(bdHolder.getBeanName(), bdHolder.getAliases()[i]);
  11.             }
  12.         }
  13.     }

很荣幸的,该BeanDefinition被加载到该BeanFactory的beanDefinitions的map中,被用来在getBean()中转换为Bean;
分享到:
评论

相关推荐

    Spring XmlBeanFactory 容器的基本实现.doc

    在实例化 `XmlBeanFactory` 时,会调用父类 `DefaultListableBeanFactory` 的初始化方法。`DefaultListableBeanFactory` 是 Spring 容器的核心,它负责管理 Bean 的生命周期,包括 Bean 的创建、初始化、依赖注入...

    spring2.5.6源码

    本文以spring框架的XmlBeanFactory为入手点进行分析,希望能够以尽量简洁明了的方式给予有需要的朋友一定的帮助。 首先来打开该类的代码,我们将看到如下代码: Java代码 public class XmlBeanFactory extends ...

    spring AOP

    XmlBeanFactory xbf = new XmlBeanFactory(res); //开启事物 StudentDao dao = (StudentDao) xbf.getBean("studentDao"); dao.save(stu); dao.save(stu1); System.out.println("ok!"); } }

    BeanFactory的实例化

    在上面的代码中,我们首先创建了一个 `FileSystemResource` 对象,指向了文件系统中的 `beans.xml` 文件,然后将其传递给 `XmlBeanFactory` 构造函数,以实例化一个 BeanFactory。 如果 `beans.xml` 文件不在项目的...

    Spring源码深度解析第二版

    XmlBeanFactory的自己直文件封装主要包括了加载Bean的XML文件和实例化Bean等。 2.5.2 加载Bean XmlBeanFactory的加载Bean主要包括了加载Bean的XML文件和实例化Bean等。 2.6 获取Bean XmlBeanFactory的获取Bean...

    Spring源码分析.pdf

    BeanFactory 接口的实现有多种,Spring 提供了多种 IOC 容器的实现,例如 XmlBeanFactory、DefaultListableBeanFactory 等。这些实现都基于模板模式,使用 Resource 接口来抽象 Bean 定义数据,并将 Xml 定义文件的...

    spring 个人小结 源码分析机制原理

    最基础的BeanFactory实现是`XmlBeanFactory`,它通过解析XML配置文件来创建Bean。在启动时,Spring会加载`web.xml`中的`contextConfigLocation`参数指定的配置文件,例如`beans.xml`。在`beans.xml`中,`&lt;import&gt;`...

    Spring常见面试题与答案,IOC AOP等

    答案:XmlBeanFactory 是 Spring 框架中的一种 BeanFactory 实现,根据 XML 文件中的定义加载 beans。 6. AOP 模块 答案:AOP 模块用于实现面向切面的编程,提供了元数据编程的功能,使得 Spring 应用可以与其他 ...

    Spring源码分析

    除了XmlBeanFactory,Spring还提供了一系列其他的IoC容器实现,例如ApplicationContext接口的实现类,它在BeanFactory的基础上提供了更多的企业级服务。如消息源支持、资源访问、事件传播等,以及更方便的Bean生命...

    69道Spring面试题和答案.docx

    本文档主要介绍了 Spring 框架的各个模块和知识点,涵盖了 Spring 的概述、使用 Spring 框架的好处、Spring 由哪些模块组成、核心容器(应用上下文)模块、BeanFactory 和 XMLBeanFactory、AOP 模块、JDBC 抽象和 ...

    spring 源码分析

    在XmlBeanFactory中,对bean定义数据的抽象是通过Resource接口完成的,而Xml定义文件的解析则通过委托给XmlBeanDefinitionReader来完成。通过这种方式,Spring将XML文件中的bean信息转换成Java中的BeanDefinition...

    Spring面试题(含答案).pdf

    2. **BeanFactory 和 XMLBeanFactory**:BeanFactory 负责实例化、配置、组装 Beans,而 XMLBeanFactory 是一种特定的 BeanFactory,它从 XML 配置文件中读取 Bean 的定义信息。 3. **AOP 模块**:面向切面编程是 ...

    Spring面试题(含答案)_20190220222455.pdf

    XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml")); // 使用factory获取bean } } ``` #### 6. XMLBeanFactory `XMLBeanFactory`是`BeanFactory`的一个实现,它从...

    Spring的69个问题.docx

    XmlBeanFactory 是 org.springframework.beans.factory.xml.XmlBeanFactory,它根据 XML 文件中定义的内容加载 beans。该容器从 XML 文件中读取配置元数据,并用它来创建一个完备的系统或应用。 AOP 模块 AOP 模块...

    JAVA_Spring基础篇.pdf

    6. **XMLBeanFactory**:最常见的BeanFactory实现是XMLBeanFactory,它读取XML配置文件来实例化和配置beans。 7. **AOP模块**:Spring的AOP模块用于实现面向切面的开发,提供了元编程的功能,并且与AOP联盟兼容,...

    Spring源码解析.pdf

    - **定义**:`XmlBeanFactory`是基于XML配置文件的`BeanFactory`实现,它能够从XML文件中读取Bean的定义,并构建相应的Bean实例。 - **构造函数**:`XmlBeanFactory(Resource resource)`,其中`Resource`参数表示...

    85道Java Spring综合面试题详解含答案(值得珍藏)

    - BeanFactory是工厂模式的一种实现,例如`XmlBeanFactory`,它根据XML配置文件创建和管理bean。 7. **Spring中的设计模式** - Spring框架中运用了多种设计模式,如工厂模式(BeanFactory)、单例模式、代理模式...

Global site tag (gtag.js) - Google Analytics