以下内容为程序代码: public class XmlBeanFactory extends DefaultListableBeanFactory { private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); public XmlBeanFactory(Resource resource) throws BeansException { this(resource, null); } public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); } } |
这个类的代码很简单,一个成员对象加两个构造函数,从这里我们可以看出,最重要的地方在于最后一个构造函数:
以下内容为程序代码: super(parentBeanFactory); this.reader.loadBeanDefinitions(resource); |
以下内容为程序代码: InputSource inputSource = new InputSource(inputStream); if (encodedResource.getEncoding() != null) { inputSource.setEncoding(encodedResource.getEncoding()); } return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); |
以下内容为程序代码: public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException { XmlBeanDefinitionParser parser = (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); return parser.registerBeanDefinitions(this, doc, resource); } |
以下内容为程序代码: public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource) throws BeanDefinitionStoreException { this.beanDefinitionReader = reader; this.resource = resource; logger.debug("Loading bean definitions"); Element root = doc.getDocumentElement(); //初始化根元素 initDefaults(root); if (logger.isDebugEnabled()) { logger.debug("Default lazy init '" + getDefaultLazyInit() + "'"); logger.debug("Default autowire '" + getDefaultAutowire() + "'"); logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'"); } preProcessXml(root);//一个空方法用于扩展 int beanDefinitionCount = parseBeanDefinitions(root);//解释配置的主要方法 if (logger.isDebugEnabled()) { logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource); } postProcessXml(root); //一个空方法用于扩展 return beanDefinitionCount; } |
以下内容为程序代码: protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException { NodeList nl = root.getChildNodes(); int beanDefinitionCount = 0; for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (IMPORT_ELEMENT.equals(node.getNodeName())) { importBeanDefinitionResource(ele); } else if (ALIAS_ELEMENT.equals(node.getNodeName())) { String name = ele.getAttribute(NAME_ATTRIBUTE); String alias = ele.getAttribute(ALIAS_ATTRIBUTE); this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias); } else if (BEAN_ELEMENT.equals(node.getNodeName())) { beanDefinitionCount++; BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); } } } return beanDefinitionCount; } |
以下内容为程序代码: else if (BEAN_ELEMENT.equals(node.getNodeName())) { beanDefinitionCount++; BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); } |
以下内容为程序代码: |
补充:
我们看到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容器的初始化过程中看得很清楚。
我们看到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容器的初始化过程中看得很清楚。