★ BeanFactory 与 ApplicationContext 区别

结论先行:ApplicationContext 是 BeanFactory 的功能超集——它通过继承链间接实现 BeanFactory 的 getBean 等基础能力,并叠加了国际化(MessageSource)、事件发布(ApplicationEventPublisher)、资源加载(ResourcePatternResolver)、Environment 与自动注册 BeanPostProcessor 等企业级能力。一句话:BeanFactory 只管"Bean 的存取",ApplicationContext 管"Bean + 应用运行时";日常开发直接用 ApplicationContext(注解时代用 AnnotationConfigApplicationContext)。

一、继承关系速览

// ApplicationContext 同时具备以下能力(多接口)
public interface ApplicationContext extends EnvironmentCapable,
        ListableBeanFactory, HierarchicalBeanFactory,
        MessageSource, ApplicationEventPublisher, ResourcePatternResolver { }

二、核心区别对比

对比项BeanFactoryApplicationContext
定位最底层 IoC 容器接口BeanFactory 的企业级增强
单例实例化时机getBean 时才创建(懒加载)启动 refresh() 时预实例化全部单例(默认 eager)
BeanPostProcessor需手动 registerBeanPostProcessor启动时自动注册(AOP/@Autowired 能工作的前提)
事件机制内建事件发布/监听
国际化MessageSource(i18n)
资源/环境ResourceLoader、Environment(profile、属性源)
注解/扫描@ComponentScan 等由后置处理器完成
常用实现DefaultListableBeanFactoryAnnotationConfigApplicationContext、ClassPathXmlApplicationContext、WebApplicationContext
场景框架内部、内存极敏感一切常规 Spring 应用

三、为什么 AOP / @Autowired 必须靠 ApplicationContext

  • @Autowired 由 AutowiredAnnotationBeanPostProcessor 处理,AOP 由 AbstractAutoProxyCreator 处理,二者都是 BeanPostProcessor;
  • BeanFactory 不会自动注册这些后置处理器,只有 ApplicationContext 在 refresh 时统一注册,所以脱离容器或只用裸 BeanFactory 时注解不生效。
// 二者都能 getBean,但能力差异很大
BeanFactory bf = new DefaultListableBeanFactory();          // 纯存取
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class); // 全功能
Object bean = ctx.getBean("orderService");
ctx.publishEvent(new OrderCreatedEvent(1L));                 // BeanFactory 做不到

常见追问 / 记忆点

  • 追问 1:为什么单例 Bean 默认预实例化?答:尽早暴露配置/初始化错误(fail-fast),同时预热常用对象;懒加载可用 @Lazy。
  • 追问 2:最常用的实现类?答:注解项目用 AnnotationConfigApplicationContext,XML 老项目用 ClassPathXmlApplicationContext,Web 环境是 WebApplicationContext。
  • 记忆点:"BeanFactory 管 Bean,ApplicationContext 管 Bean + 应用(事件/资源/国际化),BeanPostProcessor 自动注册是关键差异"。
笔记加载中…