【spring】BeanFactory容器和ApplicationContext容器的区别

接口 BeanFactory 和 ApplicationContext 都是用来从容器中获取 Spring beans 的,但是,他们二者有很大不同

首先要知道什么是 Spring Bean、什么是 Spring 容器

1. 什么是 Spring Bean?

这是一个非常简单而又很复杂的问题,通常来说,Spring beans 就是被 Spring 容器所管理的 Java 对象,来看一个简单的例子:

public class myTest {

    private String message;

    public void setMessage(String message) {
        this.message = message;
    }

    public void getMessage() {
        System.out.println("My Message : " + message);
    }
}

在基于 XML 的配置中, beans.xml 为 Spring 容器管理 bean 提供元数据

2. 什么是 Spring 容器

Spring 容器负责实例化,配置和装配 Spring beans,下面来看如何为 IoC 容器配置我们的 HelloWorld POJO:

<?xml version = "1.0" encoding = "UTF-8"?>
<beans xmlns = "http://www.springframework.org/schema/beans"   xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"   xsi:schemaLocation = "http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    <bean id = "helloWorld" class = "com.test.myTest">
        <property name = "message" value = "Hello World!"/>
    </bean>
</beans>

现在,它已经被 Spring 容器管理了,接下来的问题是:我们怎样获取它?

3. BeanFactory 和 ApplicationContext 的不同点

3.1 BeanFactory 接口

这是一个用来访问 Spring 容器的 root 接口,要访问 Spring 容器,我们将使用 Spring 依赖注入功能,使用 BeanFactory 接口和它的子接口

特性:Bean 的实例化/串联

通常情况,BeanFactory 的实现是使用懒加载的方式,这意味着 beans 只有在我们通过 getBean() 方法直接调用它们时才进行实例化

实现 BeanFactory 最常用的 API 是 XMLBeanFactory,这里是如何通过 BeanFactory 获取一个 bean 的例子:

package com.zoltanraffai;  
import org.springframework.core.io.ClassPathResource;  
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.beans.factory.xml.XmlBeanFactory; 
public class HelloWorldApp{ 
   public static void main(String[] args) { 
      XmlBeanFactory factory = new XmlBeanFactory (new ClassPathResource("beans.xml")); 
      HelloWorld obj = (HelloWorld) factory.getBean("helloWorld");    
      obj.getMessage();    
   }
}

3.2 ApplicationContext 接口

ApplicationContext 是 Spring 应用程序中的中央接口,用于向应用程序提供配置信息,它继承了 BeanFactory 接口,所以 ApplicationContext 包含 BeanFactory 的所有功能以及更多功能!它的主要功能是支持大型的业务应用的创建。

特性:

  • 继承MessageSource,因此支持国际化。

  • 统一的资源文件访问方式。

    扩展了ResourceLoader(资源加载器)接口,有三个经常用到:

    1。ClassPathXmlApplicationContext:从类路径中的XML文件载入上下文定义信息,把上下文定义文件当作类路径资源。
    
    2。FileSystemXmlApplicationContext:从文件系统中的XML文件载入上下文定义信息。
    
    3。XmlWebApplicationContext:从Web系统中的XMl文件载入上下文信息。
    
  • 强大的事件机制(Event)

    基本上牵涉到事件(Event)方面的设计,就离不开观察者模式。ApplicationContext的事件机制主要通过ApplicationEventApplicationListener这两个接口来提供的,和java swing中的事件机制一样。即当ApplicationContext中发布一个事件的时,所有扩展了ApplicationListener的Bean都将会接受到这个事件,并进行相应的处理。

    Spring提供了部分内置事件,主要有以下几种:

    ContextRefreshedEvent :ApplicationContext发送该事件时,表示该容器中所有的Bean都已经被装载完成,此ApplicationContext已就绪可用 
    ContextStartedEvent:生命周期 beans的启动信号  
    ContextStoppedEvent: 生命周期 beans的停止信号  
    ContextClosedEvent:ApplicationContext关闭事件,则context不能刷新和重启,从而所有的singleton bean全部销毁(因为singleton bean是存在容器缓存中的) 
    

    虽然,spring提供了许多内置事件,但用户也可根据自己需要来扩展spring中的事物。注意,要扩展的事件都要实现ApplicationEvent接口。

  • 事件传递

  • 对Web应用的支持
    BeanFactory通常以编程的方式被创建不同的是,ApplicationContext能以声明的方式创建,如使用ContextLoader。当然你也可以使用ApplicationContext的实现之一来以编程的方式创建ApplicationContext实例 。

与 BeanFactory 懒加载的方式不同,它是预加载,所以,每一个 bean 都在 ApplicationContext 启动之后实例化,这里是 ApplicationContext 的使用例子:

它还可以为Bean配置lazy-init=true来让Bean延迟实例化

package com.zoltanraffai;  
import org.springframework.core.io.ClassPathResource;  
import org.springframework.beans.factory.InitializingBean; 
import org.springframework.beans.factory.xml.XmlBeanFactory; 
public class HelloWorldApp{ 
   public static void main(String[] args) { 
      ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml"); 
      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");    
      obj.getMessage();    
   }
}

3.2.1 结构图

ApplicationContext 接口的实现类,最常用的几个实现类为:

  • ClassPathXmlApplicationContext(基于 xml 配置文件的 Ioc 容器)

    main方法可以直接调用

  • AnnotationConfigApplicationContext(基于注解的 Ioc 容器)

  • XmlWebApplicationContext(web应用中基于 xml 文件的 Ioc 容器)

    web应用,例如tomcat,web.xml配置了applicationContext.xml,负责加载applicationContext.xml。也就说tocmat内,默认的是XmlWebApplicationContext容器。前提是传统的外置tomcat,且非springboot项目,后者更复杂,暂不提

  • ServletWebServerApplicationContext springboot使用内置tocmat 作为web容器时的IOC容器类(默认内置了一个容器,无需用户定义,当使用外部tomcat时,需由用户指定),主要和前文提到的传统的外置tomcat,且非springboot项目默认使用XmlWebApplicationContext作为spring ioc容器

    更多的ServletWebServerApplicationContext 信息 参见 ServletWebServerApplicationContext、SpringServletContainerInitializer、WebApplicationInitializer

在这里插入图片描述

从 ApplicationContext 体系结构图分析整理类继承关系如下:

ApplicationContext
    WebApplicationContext
        ConfigurableWebApplicationContext
    ConfigurableApplicationContext
        AbstractApplicationContext
            AbstractRefreshableApplicationContext
                AbstractRefreshableConfigApplicationContext
                    -- ClasspathXmlApplicationContext
                    AbstractRefreshableWebApplicationContext
                        -- XmlWebApplicationContext
            GenericApplicationContext
                -- AnnotationConfigApplicationContext   

3.3 总结

ApplicationContext 包含 BeanFactory 的所有特性,通常推荐使用前者。但是也有一些限制情形,比如移动应用内存消耗比较严苛,在那些情景中,使用更轻量级的 BeanFactory 是更合理的。然而,在大多数企业级的应用中,ApplicationContext 是你的首选。


参考:
《BeanFactory和ApplicationContext的区别(Bean工厂和应用上下文)》

《ApplicationContext 体系结构》 提供ApplicationContext 继承关系图

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值