文章目录
- 一、BeanFactory
- 1、BeanFactory 的作用
- 2、BeanFactory的实现类
- 3、BeanFactory的创建
- 4、BeanFactory与ApplicationContext的关系
- 5、BeanFactory的工作原理
- 二、ApplicationContext
- 1、ApplicationContext 的作用
- 2、ApplicationContext 的实现类
- 3、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
版本后被废弃,建议使用GenericXmlApplicationContext
或ClassPathXmlApplicationContext
等更现代的容器实现。 - 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 {@Beanpublic 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
方法。