• spring中的BeanFactory与ApplicationContext的作用和区别?


    20180508 check

    在Spring中,两个最基本最重要的包是 org.springframework.beans 和 org.springframework.context. 这两个包中的代码为Spring的反向控制 特性(也叫作依赖注射)提供了基础。

    1. BeanFactory类结构体系:

    BeanFactory接口及其子类定义了Spring IoC容器体系结构,由于BeanFactory体系非常的庞大和复杂,因此要理解Spring IoC,需要先理清BeanFactory的继承机构。

    一个BeanFactory可以用接口org.springframework.beans.factory.BeanFactory表示, 这个接口有多个实现。 最常使用的的简单的eanFactory实现是org.springframework.beans.factory.xml.XmlBeanFactory

    2. ApplicationContext的结构体系:

    ApplicationContext接口是一个BeanFactory基础上封装了更多功能的,Spring中最为常用的IoC容器,其包含两个子接口:ConfigurableApplicationContext、WebApplicationContext。

      1、容器是spring的核心,使IoC管理所有和组件
      2、spring的两种容器:a、BeanFactoy
                                    b、ApplicationContext应用上下文
      3、BeanFactory:BeanhFactory使用延迟加载所有的Bean,为了从BeanhFactory得到一个Bean,只要调用getBean()方法,就能获得Bean

      4、ApplicationContext:a、提供文本信息解析,支持I18N(MessageResource接口)
                             b、提供载入文件资源的通用方法
                             c、向注册为监听器的Bean发送事件
                             d、ApplicationContext接口扩展BeanFactory接口
                             e、ApplicationContext提供附加功能
      5、ApplicationContext的三个实现类:a、ClassPathXmlApplication:把上下文文件当成类路径资源
                                         b、FileSystemXmlApplication:从文件系统中的XML文件载入上下文定义信息

                                         c、XmlWebApplicationContext:从Web系统中的XML文件载入上下文定义信息

    *******************************

    Context包的基础是位于org.springframework.context包中的ApplicationContext接口。它是由BeanFactory接口集成而来,提供BeanFactory所有的功能。为了以一种更像面向框架的方式工作,context包使用分层和有继承关系的上下文类,包括:

    1.MessageSource,提供对i18n消息的访问;

    2.资源访问,比如URL和文件;

    3.事件传递给实现了ApplicationListener接口的bean;

    4.载入多个(有继承关系)上下文类,使得每一个上下文类都专注于一个特定的层次,比如应用的Web层

    在ApplicationContext的诸多实现中,有三个经常用到:

    1。ClassPathXmlApplicationContext:从类路径中的XML文件载入上下文定义信息,把上下文定义文件当作类路径资源。

    2。FileSystemXmlApplicationContext:从文件系统中的XML文件载入上下文定义信息。

    3。XmlWebApplicationContext:从Web系统中的XMl文件载入上下文信息。

    例如:

      //通过ApplicationContext来获取Spring的配置文件
      ApplicationContext actx=new FileSystemXmlApplicationContext("applicationContext.xml.xml");
      //通过Bean的id来获取bean
      Hello hello=(Hello)actx.getBean("HelloWorld");

    无论是那种实现,都是用getBean()方法,这不要奇怪,因为ApplicationContext接口扩展自BeanFactory接口。

    应用上下文与Bean工厂的另一个重要的区别就是关于单实例Bean是如何载入的。Bean工厂延迟载入所有的Bean,直到getbean()方法被调用是Bean才被创建。应用上下文则会在上下文启动后预载入所有的单实例Bean。通过预载入单实例bean ,确保当你需要的时候,你就不用等待,因为它们已经创建好了。

     载入配置文件的方法:

     ApplicationContext

    1. ClassPathXmlApplicationContext  编译路径总有三种方式:
             1)ApplicationContext factory=new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
          2)ApplicationContext factory=new ClassPathXmlApplicationContext("applicationContext.xml");  
       3)ApplicationContext factory=new ClassPathXmlApplicationContext("file:E:/Workspaces/MyEclipse 8.5/Hello/src/applicationContext.xml");
    2.  FileSystemXmlApplicationContext用文件系统的路径总有两种相对与绝对路径
        1) ApplicationContext factory=new FileSystemXmlApplicationContext("src/applicationContext.xml");
        2) ApplicationContext factory=new FileSystemXmlApplicationContext("E:/Workspaces/MyEclipse 8.5/Hello/src/applicationContext.xml");
    3. XmlWebApplicationContext   是专为Web工程定制的。
        ServletContext servletContext = request.getSession().getServletContext();
        ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext );
    ****************************************

      6、在默认情况下,Bean全都是单态,在<bean>中的singleton为false
      7、<bean>中的id属性必须遵循Java规范,而name属性可以不遵循
      8、Bean的实例化的时候需要一些初始化的动作,同样当不再使用的时候,需要从容器中将其销毁
      9、对象的初始化:<bean init-method="方法名">
      10、对象的销毁:<bean destroy-method="方法名">
          销毁对象的过程:a、主线程先被中断
                                b、Java虚拟机使用垃圾回收机制回收Bean对象
      11、Bean设置:设值注入:1)简单配置:<bean id="xxx" class="Bean的全称类名">
                                                     <property name="xx" value="xxxxx"></property>
                                                 </bean>
                                          value中的值可以是基本数据类型或者String类型,spring将会自动判断设置的类型并且将其转换成合适的值

                              2)引用配置:<bean id="xxx" class="Bean的全称类名">
                                                 <property name="xx" ref="xxxxx"></property>
                                             </bean>
                                          ref中的值是引用数据类型,spring容器会完成获取工作
                              3)List和数组:<bean id="xxx" class="Bean的全称类名">
                                               <property name="list">
                                                   <list>
                                                    <value></value>
                                                    <ref bean=""/>
                                                   </list>
                                               </property>
                                            </bean>
                                            list元素内可以是任何元素,但不能违背Bean所需要的对象类型

                              4)Set配置:和<list>一样,将<list>改成<set>
                              5)Map配置:Map中的每条数据是由一个键和一个值组成,用<entry>元素来定义

                                         <bean id="xxx" class="Bean的全称类名">
                                               <property name="list">
                                                  <entry key="key1">
                                                      <value></value>
                                                  </entry>
                                               </property>
                                            </bean>
                                         <bean id="xxx" class="Bean的全称类名">
                                               <property name="list">
                                                  <entry key="key1">
                                                      <ref bean=""/>
                                                  </entry>
                                               </property>
                                            </bean>
                                    注意:配置entry时,属性key的值只能是String,因为Map通常用String作为主键

                              6)Properties配置:使用<props>和<map>相似,最大区别是<prop>的值都是String

                      注意:使用设值注入必须要有set方法,通过name属性找set方法

                      优势:a、通过set()方法设定更直观,更自然

                            b、当依赖关系较复杂时,使用set()方法更清晰
                    构造子注入:必须要有无参和带参的构造方法,加上index(值从0开始)属性避免注入混淆

                               <constractor-arg>

                   注意:设值注入可以和构造子注入混合使用。先调用构造方法产生对象,再调用set()方法赋值。但只使用设值注入时,会先调用无参的构造方法

                   优势:a、依赖关系一次性设定,对外不准修改

                         b、无需关心方式

                         c、注入有先后顺序,防止注入失败

    Spring的IoC容器就是一个实现了BeanFactory接口的可实例化类。事实上,Spring提供了两种不同的容器:一种是最基本的BeanFactory,另一种是扩展的ApplicationContext。BeanFactory 仅提供了最基本的依赖注入支持,而 ApplicationContext 则扩展了BeanFactory ,提供了更多的额外功能。二者对Bean的初始化也有很大区别。BeanFactory当需要调用时读取配置信息,生成某个类的实例。如果读入的Bean配置正确,则其他的配置中有错误也不会影响程序的运行。而ApplicationContext 在初始化时就把 xml 的配置信息读入内存,对 XML 文件进行检验,如果配置文件没有错误,就创建所有的Bean ,直接为应用程序服务。相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。

    ApplicationContext会利用Java反射机制自动识别出配置文件中定义的BeanPostProcessor、InstantiationAwareBeanPostProcessor和BeanFactoryPostProcessor,并自动将它们注册到应用上下文中;而BeanFactory需要在代码中通过手工调用addBeanPostProcessor()方法进行注册。

    Bean装配实际上就是让容器知道程序中都有哪些Bean,可以通过以下两种方式实现:
    配置文件(最为常用,体现了依赖注入DI的思想)
    编程方式(写的过程中向BeanFactory去注册)

    作用:

    1. BeanFactory负责读取bean配置文档,管理bean的加载,实例化,维护bean之间的依赖关系,负责bean的声明周期。
    2. ApplicationContext除了提供上述BeanFactory所能提供的功能之外,还提供了更完整的框架功能:

    a. 国际化支持
    b. 资源访问:Resource rs = ctx. getResource(“classpath:config.properties”), “file:c:/config.properties”
    c. 事件传递:通过实现ApplicationContextAware接口
    3. 常用的获取ApplicationContext的方法:
    FileSystemXmlApplicationContext:从文件系统或者url指定的xml配置文件创建,参数为配置文件名或文件名数组
    ClassPathXmlApplicationContext:从classpath的xml配置文件创建,可以从jar包中读取配置文件
    WebApplicationContextUtils:从web应用的根目录读取配置文件,需要先在web.xml中配置,可以配置监听器或者servlet来实现
    <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    <servlet>
    <servlet-name>context</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    </servlet>
    这两种方式都默认配置文件为web-inf/applicationContext.xml,也可使用context-param指定配置文件
    <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/myApplicationContext.xml</param-value>
    </context-param>

  • 相关阅读:
    堆与堆排序
    利用openssl进行RSA加密解密
    [转载]编辑器圣战
    七月底的小结
    计算机是怎么样工作的?
    Linux进程地址空间之初探:一
    微软2013暑期实习笔试回忆
    微软编程之美资格赛
    微软编程之美初赛
    rootkit:实现隐藏进程
  • 原文地址:https://www.cnblogs.com/skyball/p/9006170.html
Copyright © 2020-2023  润新知