谈到Spring,那势必要讲讲容器 BeanFactory 和 ApplicationContext。
BeanFactory是什么?
BeanFactory,其实就是 Spring 容器,用于管理和操作 Spring 容器中的 Bean。可能此时又有初学的小伙伴会问:Bean 是什么?其实这就是对象,只不过这个对象是被 Spring Ioc 容器管理的。
BeanFactory 的主要功能
1. 创建 Bean
BeanFactory
负责创建和管理 Bean 的生命周期。简单来说,它就像是一个工厂,负责生产(创建)各种对象(Bean)。这些对象在创建时,BeanFactory
会根据配置文件(如 XML 文件)中的定义,初始化这些对象的属性和行为。
2. 依赖注入
BeanFactory
通过依赖注入(DI)机制将依赖关系注入到 Bean 中。想象一下,一个对象(Bean)需要使用另一个对象(依赖)来完成某些任务。BeanFactory
会自动将这些依赖对象注入到需要它们的 Bean 中,这样你就不需要在代码中手动创建这些依赖对象,使得代码更加简洁和易于维护。
3. 获取 Bean
BeanFactory
提供了方法来获取 Bean 实例。当你需要使用某个 Bean 时,你可以通过 BeanFactory
提供的方法(如 getBean
)来获取这个 Bean 的实例。这个过程就像是从工厂中取出一个已经生产好的产品一样简单。
下面举一个例子:通过 BeanFactory 获取所有的单例 Bean。
@SpringBootApplication
public class Application {
public static void main(String[] args) {
// 启动 Spring 应用
ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);
// 通过反射获取 DefaultSingletonBeanRegistry 类中的 singletonObjects 字段
Field singletonObjectsField;
try {
singletonObjectsField = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjectsField.setAccessible(true);
// 获取当前 Spring 容器的 BeanFactory
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 通过反射获取 singletonObjects 字段的值
Map<String, Object> singletonObjects = (Map<String, Object>) singletonObjectsField.get(beanFactory);
// 打印所有单例 Bean
singletonObjects.forEach((beanName, beanInstance) -> {
System.out.println(beanName + ": " + beanInstance.getClass().getName());
});
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
// 关闭 Spring 容器
context.close();
}
}
另外,需要自己提前创建好 bean。方法有很多,简便点,直接加类上加 @Component 即可,这使得该类可以被 Spring 容器自动检测并注册为一个 Bean。如下所示:
@Component
public class MyComponent {
public void doSomething() {
System.out.println("Doing something...");
}
}
那它与 ApplicationContext 有什么区别?
可以从图中看出,ApplicationContext
可以说是更高级的容器,它继承并扩展了 BeanFactory
的功能,提供了更多的功能。具体来说,ApplicationContext
多继承了以下几个接口:
-
MessageSource
:提供国际化消息支持,可以用于多语言应用。 -
EnvironmentCapable
:提供环境变量的访问功能,可以获取系统环境变量和配置文件中的属性。 -
ResourcePatternResolver
:提供资源路径解析功能,可以方便地加载资源文件。 -
ApplicationEventPublisher
:提供事件发布功能,可以发布和监听应用事件。
总结
BeanFactory
:是最基本的 Spring 容器接口,提供 Bean 的创建、配置和组装功能。适用于资源受限的环境,启动速度快。
ApplicationContext
:是 BeanFactory
的子接口,提供了更多的高级功能,如事件传播、国际化消息支持、资源访问等。适用于大多数企业级应用,启动时会自动初始化所有单例 Bean,提供更多的功能和便利性。