zoukankan      html  css  js  c++  java
  • spring揭密学习笔记(3)-spring ioc容器:Spring的IoC容器之BeanFactory

    1. Spring的IoC容器和IoC Service Provider的关系

    Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所示。

     2. Spring提供了两种容器类型:BeanFactory和ApplicationContext。

     BeanFactory。

    基础类型IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)

    只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需要的资源有限

    对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适IoC容器选择。
     ApplicationContext。

    ApplicationContext在BeanFactory的基础上构建,是相对比较高级的容器实现,

    除了拥有BeanFactory的所有支持,ApplicationContext还提供了其他高级特性,比如事件发布、国际化信息支持等,这些会在后面详述。

    ApplicationContext所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。

    所以,相对于BeanFactory来说,ApplicationContext要求更多的系统资源,

    同时,因为在启动时就完成所有初始化,容器启动时间较之BeanFactory也会长一些。

    在那些系统资源充足,并且要求更多功能的场景中,AlicationContext类型的容器是比较合适的选择



     4. BeanFactory和ApplicationContext 之间的关系

    5.BeanFactory介结 

    BeanFactory可以完成作为IoC Service Provider的所有职责,包括业务对象的注册和对象间依赖关系的绑定。

    对于独立的应用程序,只有主入口类才会跟容器的API直接耦合

    6.容器启动三种代码写法:

    不过,现在既然有了BeanFactory,我们通常只需将“生产线图纸”交给BeanFactory,让BeanFactory为我们生产一个FXNewsProvider,如以下代码所示: 

    BeanFactory container = 
    new XmlBeanFactory(new ClassPathResource("配置文件路径"));
    FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider");
    newsProvider.getAndPersistNews();
    或者如以下代码所示:
    ApplicationContext container = 
    new ClassPathXmlApplicationContext("配置文件路径");
    FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider");
    newsProvider.getAndPersistNews();

    亦或如以下代码所示:

    ApplicationContext container =
    new FileSystemXmlApplicationContext("配置文件路径");
    FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("djNewsProvider");
    newsProvider.getAndPersistNews();

    7.BeanFactory的对象注册与依赖绑定的三种方式

      直接编码方式,外部配置文件方式,注解方式

    8.依赖绑定方式--直接编码方式

    BeanFactory只是一个接口,我们最终需要一个该接口的实现来进行实际的Bean的管理,Default- ListableBeanFactory就是这么一个比较通用的BeanFactory实现类。DefaultListableBeanFactory除了间接地实现了BeanFactory接口,还实现了BeanDefinitionRegistry接口,该接口才是在BeanFactory的实现中担当Bean注册管理的角色。基本上,BeanFactory接口只定义如何访问容器内管理的Bean的方法,各个BeanFactory的具体实现类负责具体Bean的注册以及管理工作。BeanDefinitionRegistry接口定义抽象了Bean的注册逻辑。通常情况下,具体的BeanFactory实现类会实现这个接口来管理Bean的注册。它们之间的关系如图4-3所示。



    9.依赖绑定方式--外部配置文件方式
    Spring的IoC容器支持两种配置文件格式:Properties文件格式和XML文件格式。

    当然,如果你愿意也可以引入自己的文件格式,前提是真的需要。采用外部配置文件时,Spring的IoC容器有一个统一的处理方式。

    通常情况下,需要根据不同的外部配置文件格式,给出相应的BeanDefinitionReader实现类,

    由BeanDefinitionReader的相应实现类负责将相应的配置文件内容读取并映射到BeanDefinition,

    然后将映射后的BeanDefinition注册到一个BeanDefinitionRegistry,之后,BeanDefinitionRegistry即完成Bean的注册和加载。

    当然,大部分工作,包括解析文件格式、装配BeanDefinition之类的工作,都是由BeanDefinitionReader的相应实现类来做的,BeanDefinitionRegistry只不过负责保管而已。

    整个过程类似于如下
    代码:
    BeanDefinitionRegistry beanRegistry = <某个BeanDefinitionRegistry实现类,通常为➥
    DefaultListableBeanFactory>;
    BeanDefinitionReader beanDefinitionReader = new BeanDefinitionReaderImpl(beanRegistry);
    beanDefinitionReader.loadBeanDefinitions("配置文件路径");
    // 现在我们就取得了一个可用的Bea nDefinitionRegistry实例

    10. Properties配置格式的加载PropertiesBeanDefinitionReader

    Spring提供了org.springframework.beans.factory.support.PropertiesBeanDefinitionReader类用于Properties格式配置文件的加载,

    所以,我们不用自己去实现BeanDefinitionReader,只要根据该类的读取规则,提供相应的配置文件即可。

    Spring提供的PropertiesBeanDefinitionReader是按照Spring自己的文件配置规则进行加载的,

    而同样的道理,你也可以按照自己的规则来提供相应的Properties配置文件。

    只不过,现在需要实现你自己的“PropertiesBeanDefinitionReader”来读取并解析。这当然有“重新发明轮子”之嫌,不过,如果你只是想试验一下,也可以尝试哦。

    11.XML配置格式的加载

    如果FX新闻系统对象按照XML配置方式进行加载的话,配置文件内容如代码清单4-7所示。代码清单4-7 FX新闻系统相关类对应XML格式的配置内<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ➥

    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    <bean id="djNewsProvider" class="..FXNewsProvider">
    <constructor-arg index="0">
    <ref bean="djNewsListener"/>
    </constructor-arg>
    <constructor-arg index="1">
    <ref bean="djNewsPersister"/>
    </constructor-arg>
    </bean>

    <bean id="djNewsListener" class="..impl.DowJonesNewsListener">
    </bean>
    <bean id="djNewsPersister" class="..impl.DowJonesNewsPersister">
    </bean>
    </beans>

    我想这段内容不需要特殊说明吧,应该比Properties文件的内容要更容易理解。如果想知道这些内
    容背后的更多玄机,往后看吧!
    有了XML配置文件,我们需要将其内容加载到相应的BeanFactory实现中,以供使用,如代码清
    单4-8所示。
    代码清单4-8 加载XML配置文件的BeanFactory的使用演示
    public static void main(String[] args)
    {
    DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory();
    BeanFactory container = (BeanFactory)bindViaXMLFile(beanRegistry);
    FXNewsProvider newsProvider = ➥
    (FXNewsProvider)container.getBean("djNewsProvider");
     newsProvider.getAndPersistNews();
    }
    public static BeanFactory bindViaXMLFile(BeanDefinitionRegistry registry)

    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(registry);
    reader.loadBeanDefinitions("classpath:../news-config.xml");
     return (BeanFactory)registry;
    // 或者直接
    //return new XmlBeanFactory(new ClassPathResource("../news-config.xml"));
    }
    与为 Properties配置文件格式提供PropertiesBeanDefinitionReader相对应,

    Spring同样为XML格式的配置文件提供了现成的BeanDefinitionReader实现,即XmlBeanDefinitionReader。
    XmlBeanDefinitionReader负责读取Spring指定格式的XML配置文件并解析,

    之后将解析后的文件内容映射到相应的BeanDefinition,并加载到相应的BeanDefinitionRegistry中(在这里是DefaultListableBeanFactory)。这时,整个BeanFactory就可以放给客户端使用了。

    除了提供XmlBeanDefinitionReader用于XML格式配置文件的加载,Spring还在DefaultListableBeanFactory的基础上构建了简化XML格式配置加载的XmlBeanFactory实现。从以上代码
    最后注释掉的一行,你可以看到使用了XmlBeanFactory之后,完成XML的加载和BeanFactory的初
    始化是多么简单。

    12.  依赖绑定方式--注解方式
    @Autowired是这里的主角,它的存在将告知Spring容器需要为当前对象注入哪些依赖对象。而
    @Component则是配合Spring 2.5中新的classpath-scanning功能使用的。

    现在我们只要再向Spring的配置文件中增加一个“触发器”,使用@Autowired和@Component标注的类就能获得依赖对象的注入了。

    代码清单4-10 配置使用classpath-scanning功能

    <?xml version="1.0" encoding="UTF-8"?> 

    <beans xmlns="http://www.springframework.org/schema/beans" ➥

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ➥

    xmlns:context="http://www.springframework.org/schema/context" ➥
    xmlns:tx="http://www.springframework.org/schema/tx" ➥
    xsi:schemaLocation="http://www.springframework.org/schema/beans ➥
    http://www.springframework.org/schema/beans/spring-beans-2.5.xsd ➥
    http://www.springframework.org/schema/context ➥
    http://www.springframework.org/schema/context/spring-context-2.5.xsd ➥
    http://www.springframework.org/schema/tx ➥
    http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
    <context:component-scan base-package="cn.spring21.project.base.package"/>
    </beans>

    <context:component-scan/>会到指定的包(package)下面扫描标注有@Component的类,如果找到,则将它们添加到容器进行管理,并根据它们所标注的@Autowired为这些类注入符合条件的依赖对象。

    在以上所有这些工作都完成之后,我们就可以像通常那样加载配置并执行当前应用程序了,如以
    下代码所示:
    public static void main(String[] args)
    {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("配置文件路径");
    FXNewsProvider newsProvider = (FXNewsProvider)container.getBean("FXNewsProvider");
    newsProvider.getAndPersistNews();
    }

     13 BeanFacotry的xml配置内容。

    所有使用 XML 文件进行配置信息加载的 Spring IoC 容器,包括 BeanFactory 和
    ApplicationContext的所有XML相应实现,都使用统一的XML格式。在Spring 2.0版本之前,这种格
    式由Spring提供的DTD规定,也就是说,

    所有的Spring容器加载的XML配置文件的头部,都需要以下形式的DOCTYPE声明: 


    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" ➥
    "http://www.springframework.org/dtd/spring-beans.dtd">
    <beans>
    ...
    </beans>

    <beans>之唯我独尊
    <beans>是XML配置文件中最顶层的元素,它下面可以包含0或者1个<description>和多个
    <bean>以及<import>或者<alias>,

    <beans>作为所有<bean>的“统帅”,它拥有相应的属性(attribute)对所辖的<bean>进行统一
    的默认行为设置,包括如下几个。

     

    <description>
    可以通过<description>在配置的文件中指定一些描述性的信息。

    <import>

    通常情况下,可以根据模块功能或者层次关系,将配置信息分门别类地放到多个配置文件中

    <alias>

    可以通过<alias>为某些<bean>起一些“外号”(别名)

    构造方法注入的XML之道constructor-arg

    <bean id="djNewsProvider" class="..FXNewsProvider">
    <constructor-arg ref="djNewsListener"/>
    <constructor-arg ref="djNewsPersister"/>

    <bean id="mockBO" class="..MockBusinessObject">
    <constructor-arg index="1" value="11111"/>
    <constructor-arg index="0" value="22222"/>
    </bean>

    setter方法注入的XML之道

    <bean id="djNewsProvider" class="..FXNewsProvider">
    <property name="newsListener" ref="djNewsListener"/> 6
    <property name="newPersistener" ref="djNewsPersister"/>
    </bean>

  • 相关阅读:
    python+hadoop=?
    Fluentd: The Missing Log Collector
    hadoop streaming 记录
    valgrind备忘
    [hadoop源码阅读][9]mapreduce概论
    GNU Binutils工具
    vim encoding
    [hadoop源码阅读][8]datanodedatanode
    Webdis: HTTP + JSON API for Redis
    gdb 小备注
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/10719986.html
Copyright © 2011-2022 走看看