Spring 中的 BeanFactory 和 ApplicationContext 详解

文章目录

Spring 中的 BeanFactory 是框架中的一个核心接口,作为 Spring 容器的基础设施,负责创建、配置和管理Bean实例,同时提供了对Bean生命周期的管理和控制。

一、BeanFactory

BeanFactory 是 Spring 框架中最基本的容器接口,定义了 Spring 容器的核心方法,用于管理 Bean 的生命周期和依赖注入。这些核心方法包括但不限于 Bean 的实例化、依赖注入、配置和管理等。通过BeanFactory,可以灵活地获取和操作Bean实例,而无需手动管理对象的创建和依赖关系。

1、BeanFactory 的作用

  • Bean 实例化:根据配置信息或注解定义,创建应用程序中需要的Bean实例。负责解析Bean定义,处理依赖关系,并将Bean实例化为可用的对象。
  • 依赖注入:将所需依赖注入到 Bean 中,确保 Bean 能正确运行。包括设置属性值、调用初始化方法等。
  • 配置和管理:根据配置文件或注解来配置和管理 Bean 实例,提供了各种方法来获取和操作 Bean 实例。
  • 生命周期管理:管理 Bean 的整个生命周期,包括创建、初始化、使用和销毁。

2、BeanFactory的实现类

Spring 提供了多个 BeanFactory 的实现类,以满足不同的需求。

  • XmlBeanFactory (已废弃):通过 XML 配置文件来创建和管理 Bean 的实例化、配置和管理的实现类。在Spring 3.1 版本后被废弃,建议使用 GenericXmlApplicationContextClassPathXmlApplicationContext 等更现代的容器实现。
  • DefaultListableBeanFactory:BeanFactory 的常用实现,提供了灵活的 Bean 注册、实例化和依赖注入机制。是许多Spring容器的基础实现。
  • XmlBeanDefinitionReader:这个类负责从 XML 文件中读取 Bean 定义并将其注册到 BeanFactory 中。
  • AnnotationConfigApplicationContext :这个类支持基于注解的配置和管理方式,提供了对 @Component@Service@Repository@Configuration 等注解的支持。

3、BeanFactory的创建

BeanFactory的创建方式主要包括XML配置方式、Java配置方式和注解配置方式:

  • XML 配置方式:这是创建 BeanFactory 的传统方式。需要在 XML 配置文件中定义 Bean 的信息,包括 Bean 的名称、类路径、属性等,通过加载配置文件来创建和管理 BeanFactory 。
  • Java配置方式:在 Java 类中定义 Bean 的创建和依赖关系,通过配置类来创建和管理 BeanFactory。通常涉及到使用 @Configuration 注解来标识配置类,并使用 @Bean 注解来定义 Bean 的实例化、配置和管理信息。
  • 注解配置方式:在 Java 类上添加相应的注解来标识该类是一个 Bean,并进行相应的配置信息。Spring 会自动扫描并创建相应的 Bean,并将其添加到 ApplicationContext 中,AnnotationConfigApplicationContext 作为其子类,同样支持注解配置方式。

4、BeanFactory与ApplicationContext的关系

BeanFactory是Spring框架中最基本的容器接口,但在实际开发中,ApplicationContext接口的使用更为广泛。ApplicationContext 是 BeanFactory 的子接口,提供了更多的功能,如国际化支持、事件传播、自动扫描组件等。因此,会使用ApplicationContext 来代替 BeanFactory。然而,理解BeanFactory仍然是理解Spring内部工作原理的基础。

5、BeanFactory的工作原理

BeanFactory 在存储和获取 Bean 时,主要通过使用数据结构(如Map)和反射机制来实现。在创建 BeanFactory 实例时,通常会使用一个容器(如HashMap)来存储Bean对象。这个容器可以将Bean的名称作为键,Bean对象作为值进行存储。当需要访问某个Bean时,可以通过名称快速地获取到对应的Bean对象。

  • 首先,当使用 Spring 的 XML 配置文件或注解定义Bean时,BeanFactory 会读取配置文件或扫描注解,并将 Bean 的相关信息解析成 BeanDefinition 对象(例如 Bean 的类名、属性、依赖关系等)。
  • 然后,BeanFactory 会将这些 BeanDefinition 对象存储在一个 Map 中,以 Bean 的名称作为键,BeanDefinition 对象作为值。
  • 当需要获取某个 Bean 时,BeanFactory 会根据 Bean 的名称从 Map 中查找对应的 BeanDefinition 对象,并根据 BeanDefinition 中的信息使用反射机制创建 Bean 的实例并返回给调用方。
  • 在创建 Bean 实例时,BeanFactory 还会处理 Bean 的依赖关系,确保所有相关的依赖都会被正确地解析和注入。

二、ApplicationContext

ApplicationContext 是 Spring 应用程序的核心,它不仅负责创建和管理Bean,还提供了多种企业级服务,如事件传播、国际化、资源加载等。是 Spring IoC 容器高级形态,提供了对 Bean 的全面管理以及对应用程序环境的支持。

1、ApplicationContext 的作用

  • Bean 的创建和管理 :负责实例化和管理应用中的所有 Bean ,包括它们的创建、配置、生命周期管理等。提供了对 Bean 的访问和控制,使得 Bean 之间的依赖关系可以通过依赖注入的方式轻松实现。
  • 依赖注入:支持依赖注入,允许 Bean 轻松地获取其依赖的其他 Bean。
  • 国际化支持 :根据不同的语言环境加载不同的资源文件实现多语言。通过继承 MessageSource 接口来支持消息解析和国际化。
  • 事件传播:可以发布事件,并允许其他组件注册监听器来处理这些事件,这种机制实现了组件之间的解耦。
  • 资源加载:提供了一个统一的接口,可以方便的加载和管理各种资源,如配置文件、XML 文件、Properties 文件等。
  • 面向切面编程:提供了对 AOP 的支持,允许通过配置切面来实现横切关注点的模块化。
  • 中央接口:为应用程序提供配置的中央接口,在应用程序运行时这是只读的,但如果实现支持这一点,则可以重新加载。
  • 继承性:后代上下文中的定义总是优先于父上下文中的定义,这意味着单个父上下文可以被整个 web 应用共享。

2、ApplicationContext 的实现类

  • ClassPathXmlApplicationContext :从类路径中获取上下文定义文件,适用于测试工具以及嵌入在 jar 中的应用程序上下文。
  • FileSystemXmlApplicationContext :从文件系统或 URL 获取上下文定义文件,适用于独立的应用程序。
  • AnnotationConfigApplicationContext :在 Spring 3.0 中引入,允许通过 Java 配置类来配置应用程序上下文,与 @Configuration@Component 等注解一起工作。

3、ApplicationContext 使用示例

以下代码示例,包括 MyBean 类的定义,该类具有一个 sayHello 方法。代码演示了如何使用 @Configuration@Bean 注解来配置 Spring 应用程序上下文,并通过 AnnotationConfigApplicationContext 来启动 Spring 容器。

1、MyBean.java

java 复制代码
```java
public class MyBean {
    public void sayHello() {
        System.out.println("Hello, Spring!");
    }
}

2、AppConfig.java

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {
    @Bean
    public MyBean myBean() {
        return new MyBean();
    }
}

3、Main.java

java 复制代码
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        // 创建应用上下文
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 获取Bean并调用方法
        // 注意:这里使用了context.getBean(Class<T> requiredType)方法,它会返回指定类型的单个Bean实例
        // 如果容器中有多个相同类型的Bean,则会抛出异常。在这个例子中,我们只有一个MyBean实例。
        MyBean myBean = context.getBean(MyBean.class);
        
        // 调用MyBean的sayHello方法
        myBean.sayHello();
        
        // (可选)关闭应用程序上下文,释放资源。在独立应用程序中,这通常不是必需的,
        // 因为JVM会在应用程序退出时自动回收资源。但在某些情况下(如Web应用程序),
        // 显式关闭上下文是一个好习惯。
        // context.close();
    }
}
  • MyBean 类定义了一个简单的 sayHello 方法,该方法打印一条消息。
  • AppConfig 类是一个配置类,使用 @Configuration 注解标记。包含一个 @Bean 注解的方法 myBean ,该方法返回一个新的 MyBean 实例。
  • Main 类是包含 main 方法的入口点。创建一个 AnnotationConfigApplicationContext 实例,将 AppConfig.class 传递给它以加载配置。它使用 context.getBean(MyBean.class) 获取 MyBean 的实例,并调用其 sayHello 方法。

4、运行 Main 类的 main 方法

复制代码
Hello, Spring!

表明Spring容器已成功创建并管理了 MyBean 实例,并且已正确调用了其 sayHello 方法。

相关推荐
Asthenia041233 分钟前
什么是消除直接左递归 - 编译原理解析
后端
Asthenia041239 分钟前
什么是自上而下分析 - 编译原理剖析
后端
Asthenia04121 小时前
什么是语法分析 - 编译原理基础
后端
Asthenia04121 小时前
理解词法分析与LEX:编译器的守门人
后端
uhakadotcom1 小时前
视频直播与视频点播:基础知识与应用场景
后端·面试·架构
Asthenia04122 小时前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz9652 小时前
ovs patch port 对比 veth pair
后端
Asthenia04123 小时前
Java受检异常与非受检异常分析
后端
uhakadotcom3 小时前
快速开始使用 n8n
后端·面试·github
JavaGuide3 小时前
公司来的新人用字符串存储日期,被组长怒怼了...
后端·mysql