Spring Framework中BeanFactory与ApplicationContext的关系与区别

介绍

BeanFactory

首先来看来自官方文档的描述:

The org.springframework.beans and org.springframework.context packages are the basis for Spring Framework's IoC container. The BeanFactory interface provides an advanced configuration mechanism capable of managing any type of object.

我们来翻译一下:

beans和context是Spring Framework的IoC容器的基础。BeanFactory接口提供了一种高级配置机制,能够管理任何类型的对象。

如何理解这段话:

IoC(Inversion of Control)是Spring Framework的核心设计思想:它将对象的创建、组装、管理交给容器(container),BeanFactory提供了访问IoC的接口,使得开发者可以更方便的使用Spring框架来实现控制和依赖注入。

引用Spring Framework API文档中的一段话:

The root interface for accessing a Spring bean container.

This is the basic client view of a bean container; further interfaces such as ListableBeanFactory and ConfigurableBeanFactory are available for specific purposes.

This interface is implemented by objects that hold a number of bean definitions, each uniquely identified by a String name.

我们再来翻译一下:

BeanFactory是访问Spring bean容器的根接口。

这是bean容器的基本客户端视图;诸如ListableBeanFactoryConfigurableBeanFactory之类的接口可用于特定目的。

这个接口是由包含许多bean定义的对象实现的,每个bean定义由一个String名称唯一标识。

如何理解这段话呢?

  1. 在Spring中,Spring bean 容器负责管理和组织JavaBean对象,BeanFactory接口定义了访问这个容器的基本方法。
  2. BeanFactory提供了最基本的访问Bean的方法,而对于更高级的功能,如列举所有Bean、配置Bean工厂等,Spring提供了其他专门的接口,如ListableBeanFactoryConfigurableBeanFactory。这些接口扩展了BeanFactory,提供了更多的功能和配置选项。
  3. 在Spring中,Bean的定义包括了Bean的类、依赖关系、配置信息等。BeanFactory接口的实现类是Spring容器,它持有多个Bean的定义,并且每个Bean都通过一个唯一的字符串名称进行标识。通过这个名称,客户端代码可以从容器中获取相应的Bean。

ApplicationContext

来自官方对Application的一段描述:

In short, the BeanFactory provides the configuration framework and basic functionality, and the ApplicationContext adds more enterprise-specific functionality. The ApplicationContext is a complete superset of the BeanFactory.

这段话不难理解:

一句话来说,BeanFactory为Spring框架提供了基础的方法和配置,ApplicationContext增加了更多企业级的方法,ApplicationContextBeanFactory的超集。

继承关系

通过继承关系可以看到ApplicationContextBeanFactory的子接口,通过继承的特性可知:ApplicationContext具有BeanFactory的所有功能,并在其基础上进行扩展。

两者的区别

两者是如何加载、获取Bean的?

准备工作:

创建类MyBean

被注入的类:

java 复制代码
/**
 * Author: 公众号:种棵代码技术树
 * Date:   2023/12/23
 */
public class MyBean {

    private String message;

    public MyBean() {
    }

    public MyBean(String message) {
        System.out.println("MyBean被实例化了");
    }

    public String getMessage() {
        return message;
    }

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

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

resource目录下创建目录:META-INF,新建文件:spring-config.xml

classpath:/META-INF/ 是一个常用的目录,特别是在Java项目中,用于存放元信息文件,如配置文件、资源文件等。

xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  https://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context
  https://www.springframework.org/schema/context/spring-context.xsd">


  	<bean id = "myBean" class="org.thinging.in.spring.ioc.overview.bean.MyBean">
      <property name="message" value="Hello, Spring!" />
    </bean>
	
</beans>

通过BeanFactory获取Bean

java 复制代码
/**
 * Author: 公众号:种棵代码技术树
 * Date:   2023/12/23
 */
public class BeanFactoryExample {
    public static void main(String[] args) {
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-config.xml");
        MyBean myBean = (MyBean) beanFactory.getBean("myBean");
        myBean.showMessage();
    }
}

输出结果:

通过ApplictaionContext获取Bean

java 复制代码
/**
 * Author: 公众号:种棵代码技术树
 * Date:   2023/12/23
 */
public class ApplicationContextExample {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/spring-config.xml");
        MyBean myBean = (MyBean) applicationContext.getBean("myBean");
        myBean.showMessage();
    }
}

输出结果:

两者都是通过配置文件加载的类,输出相同的结果,那么他们是不是同一个对象呢?

java 复制代码
/**
 * Author: 公众号:种棵代码技术树
 * Date:   2023/12/23
 */
public class ApplicationContextExample {
    public static void main(String[] args) {
        //使用ApplicationContext
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
        MyBean applicationContextBean = (MyBean) applicationContext.getBean("myBean");
        applicationContextBean.showMessage();

        //使用BeanFactory
        BeanFactory beanFactory = new ClassPathXmlApplicationContext("classpath:/META-INF/dependency-lookup-context.xml");
        MyBean beanFactoryBean = (MyBean) beanFactory.getBean("myBean");
        beanFactoryBean.showMessage();

        //比较两者的引用
        boolean flag = applicationContextBean == beanFactoryBean;
        System.out.println("两者是否为同一个对象:" + flag);
    }
}

以上说明两者的引用不是同一个对象。

官方文档中描述的区别

在Spring Framework官方文档中指出了ApplicationContext相较于BeanFactory增加了以下特性:

  • Easier integration with Spring's AOP features
    • 通过ApplicationContext可以更好的集成AOP。
  • Message resource handling (for use in internationalization)
    • 更好的处理国际化
  • Event publication
    • 支持事件机制,Spring的事件机制允许一个组件发布事件,而其他组件可以监听并响应这些事件。
  • Application-layer specific contexts such as the WebApplicationContext for use in web applications.
    • Spring的上下文(ApplicationContext)是一个IoC容器,用于管理和组织应用程序中的组件(Beans)。不同类型的应用程序可能需要不同的上下文。例如,对于Web应用程序,Spring提供了WebApplicationContext ,它在ApplicationContext的基础上添加了一些特定于Web的功能,如处理Web相关的Bean(例如控制器)、处理Web请求等。

总结

在Spring框架中,由Spring IoC容器管理的构成应用程序骨架的对象被称为"beans"。一个bean是由Spring IoC容器实例化、组装和管理的对象。从另一个角度看,一个bean也只是应用程序中的众多对象之一。Beans以及它们之间的依赖关系都体现在容器所使用的配置元数据中。

  1. Bean: 由Spring IoC容器管理的对象,通过容器进行实例化、组装和生命周期管理。Beans的配置信息被反映在Spring IoC容器的配置元数据中。
  2. ApplicationContext: 是BeanFactory的超集,提供了更多的企业级功能。ApplicationContext是Spring IoC容器的一种,负责加载、实例化、配置和管理beans。

后续内容文章持续更新中...

近期发布。


关于我

👋🏻你好,我是Debug.c。微信公众号:种棵代码技术树 的维护者,一个跨专业自学Java,对技术保持热爱的bug猿,同样也是在某二线城市打拼四年余的Java Coder。

🏆在掘金、CSDN、公众号我将分享我最近学习的内容、踩过的坑以及自己对技术的理解。

📞如果您对我感兴趣,请联系我。

若有收获,就点个赞吧,喜欢原图请私信我。

相关推荐
间彧14 分钟前
Spring Boot分布式WebSocket实现指南:项目实战与代码详解
后端
间彧30 分钟前
Spring Boot集成WebSocket项目实战详解
后端
xyy20251 小时前
Spring事务的传播方式
java·数据库·spring
该用户已不存在2 小时前
工具用得好,Python写得妙,9个效率工具你值得拥有
后端·python·编程语言
深色風信子3 小时前
SpringBoot 集成 LangChain4j RAG Redis 搜索
spring boot·langchain4j rag·rag redis 搜索·rag redis·springboot rag·rag 搜索
im_AMBER3 小时前
Web 开发 30
前端·笔记·后端·学习·web
码事漫谈3 小时前
LLVM IR深度技术解析:架构、优化与应用
后端
码事漫谈3 小时前
C++ 中的类型转换:深入理解 static_cast 与 C风格转换的本质区别
后端
小蒜学长3 小时前
springboot餐厅信息管理系统设计(代码+数据库+LW)
java·数据库·spring boot·后端
Chh432244 小时前
React 新版
后端