Spring IoC 容器之 BeanFactory 修改中...

        Spring 提供了两种容器类型:BeanFactory ApplicationContext

        BeanFactory:是基础类型IoC容器,提供完整的IoC服务支持。如果没有特殊指定,默认采用延迟初始化策略(lazy-load)。只有当客户端对象需要访问容器中的某个受管对象的时候,才对该受管对象进行初始化以及依赖注入操作。所以,相对来说,容器启动初期速度较快,所需要的资源有限。对于资源有限,并且功能要求不是很严格的场景,BeanFactory是比较合适的IoC容器选择。//BeanFactory采用延迟初始化,功能简单,初始速度快

        ApplicationContext:ApplicationContext 在 BeanFactory 的基础上构建,是相对比较高级的容器实现,除了拥有 BeanFactory 的所有支持,ApplicationContext 还提供了其他高级特性,比如事件发布、国际化信息支持等。ApplicationContext 所管理的对象,在该类型容器启动之后,默认全部初始化并绑定完成。所以,相对于BeanFactory来说,ApplicationContext 要求更多的系统资源,同时,因为在启动时就完成所有初始化,容器启动时间较之 BeanFactory 也会长一些。在那些系统资源充足,并且要求更多功能的场景中,ApplicationContext 类型的容器是比较合适的选择。//启动时就完成所有初始化,功能丰富,初始速度慢

        BeanFactory 和 ApplicationContext 之间的继承关系如下图所示:

        ApplicationContext 间接继承自 BeanFactory,所以说它是构建于 BeanFactory 之上的 IoC 容器。

        接下来,我们重点探讨一下Spring IoC 容器中的 BeanFactory,ApplicationContext 将在后续的文章中探讨。

1、BeanFactory 和 BeanFactory 的简单使用

        BeanFactory,顾名思义,就是生产Bean的工厂。主要功能有两个:业务对象的构建管理和业务对象间的依赖绑定

        如果要使用 BeanFactory 构建对象,那么应该告知 BeanFactory 需要构建哪些对象。这个告知对象信息的描述,在 Spring 中一般用 xml 文件或者注解的方式来实现。接下来,让我们使用代码来描述这一过程。

        首先,定义一个简单的类(bean) MessageService:

public class MessageService {

    public void sendMessage(String message) {
        System.out.println("MessageService sendMessage:" + message);
    }
}

        接下来,创建一个 Spring 的配置文件 beans.xml,并在其中定义这个 Bean:

<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.xsd">

    <bean id="messageService" class="com.swadian.spring.MessageService" />

</beans>

        现在,使用 BeanFactory 来加载这些 Bean,并且使用它们:

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

public class BeanFactoryExample {
    public static void main(String[] args) {
        // 加载 Spring 配置文件
        BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("beans.xml"));

        // 从容器中获取 Bean
        MessageService messageService = (MessageService) beanFactory.getBean("messageService");

        // 使用获取的 Bean
        messageService.sendMessage("Hello BeanFactory");
    }
}

//输出:
MessageService sendMessage:Hello BeanFactory

        上述示例演示了如何使用 BeanFactory 加载配置文件中定义的 Bean,并从容器中获取它们。

        注:执行下列代码的前提是需要引入spring/springboot的依赖,本文中的代码都是基于 springboot 2.1.4.RELEASE 进行演示(使用Spring,主要是方便环境搭建)

        IOC (Inversion of Control) 容器是 Spring 的核心,也可以称为 Spring 容器。Spring 通过 IoC 容器来管理对象的实例化和初始化,以及对象从创建到销毁的整个生命周期

        Spring 中使用的对象都由 IoC 容器管理,不需要我们手动使用 new 创建对象。由 IoC 容器管理的对象称为 Spring Bean,Spring Bean 就是 Java 对象,和使用 new 创建的对象没有区别。

        Spring 通过读取 XML 或 Java 注解中的信息来获取哪些对象需要实例化。

        Spring 提供 2 种不同类型的 IoC 容器,即 BeanFactory 和 ApplicationContext 容器。

1. BeanFactory 容器

        BeanFactory 是最简单的容器,由 org.springframework.beans.factory.BeanFactory 接口定义,采用懒加载(lazy-load),所以容器启动比较快。BeanFactory 提供了容器最基本的功能。

        为了能够兼容 Spring 集成的第三方框架(如 BeanFactoryAware、InitializingBean、DisposableBean),所以目前仍然保留了该接口。

        简单来说,BeanFactory 就是一个管理 Bean 的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。

        BeanFactory 接口有多个实现类,最常见的是 org.springframework.beans.factory.xml.XmlBeanFactory。使用 BeanFactory 需要创建 XmlBeanFactory 类的实例,通过 XmlBeanFactory 类的构造函数来传递 Resource 对象。如下所示。

Resource resource = new ClassPathResource("applicationContext.xml");
BeanFactory factory = new XmlBeanFactory(resource); //XmlBeanFactory已过期

2. ApplicationContext 容器

        ApplicationContext 继承了 BeanFactory 接口,由 org.springframework.context.ApplicationContext 接口定义,对象在启动容器时加载。ApplicationContext 在 BeanFactory 的基础上增加了很多企业级功能,例如 AOP、国际化、事件支持等。

        ApplicationContext 接口有两个常用的实现类,具体如下。

1)ClassPathXmlApplicationContext

        该类从类路径 ClassPath 中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new ClassPathXmlApplicationContext(String configLocation);

        在上述代码中,configLocation 参数用于指定 Spring 配置文件的名称和位置,如 Beans.xml。

2)FileSystemXmlApplicationContext

        该类从指定的文件系统路径中寻找指定的 XML 配置文件,并完成 ApplicationContext 的实例化工作,具体如下所示。

ApplicationContext applicationContext = new FileSystemXmlApplicationContext(String configLocation);

        它与 ClassPathXmlApplicationContext 的区别是:在读取 Spring 的配置文件时,FileSystemXmlApplicationContext 不会从类路径中读取配置文件,而是通过参数指定配置文件的位置。即 FileSystemXmlApplicationContext 可以获取类路径之外的资源,如“F:/workspaces/Beans.xml”。

        通常在 Java 项目中,会采用 ClassPathXmlApplicationContext 类实例化 ApplicationContext 容器的方式,而在 Web 项目中,ApplicationContext 容器的实例化工作会交由 Web 服务器完成。Web 服务器实例化 ApplicationContext 容器通常使用基于 ContextLoaderListener 实现的方式,它只需要在 web.xml 中添加如下代码:

<!--指定Spring配置文件的位置,有多个配置文件时,以逗号分隔-->
<context-param>
    <param-name>contextConfigLocation</param-name>
    <!--spring将加载spring目录下的applicationContext.xml文件-->
    <param-value>
        classpath:spring/applicationContext.xml
    </param-value>
</context-param>
<!--指定以ContextLoaderListener方式启动Spring容器-->
<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>

        需要注意的是,BeanFactory 和 ApplicationContext 都是通过 XML 配置文件加载 Bean 的。

        二者的主要区别在于,如果 Bean 的某一个属性没有注入,使用 BeanFacotry 加载后,第一次调用 getBean() 方法时会抛出异常,而 ApplicationContext 则会在初始化时自检,这样有利于检查所依赖的属性是否注入。

        因此,在实际开发中,通常都选择使用 ApplicationContext,只有在系统资源较少时,才考虑使用 BeanFactory。

IOC容器的设计与实现扩展

Spring IoC容器与应用上下文的设计与实现 - 超级小小黑 - 博客园SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一)icon-default.png?t=N7T8https://www.cnblogs.com/hello-shf/p/11006750.html#_label0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值