ApplicationContext 与 BeanFactory 区别

一、ApplicationContext

这里是一个我们使用Spring时常用获取 bean 的代码:

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
A demo = (A) ctx.getBean("a");

二、BeanFactory

但是如果使用BeanFactory获取Bean,则需要执行以下的步骤:过程中新增使用了一些其它的类,并且遗弃了ApplicationContext类的使用。

DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
A demo = (A) beanFactory.getBean("a");

三、结构分析

public interface ListableBeanFactory extends BeanFactory {
    boolean containsBeanDefinition(String var1);
    ....
}

public interface ApplicationContext extends ListableBeanFactory{
    ...
}

可能是我看的Spring代码的版本问题,和网上其它的一些结构有些小的区别,但是大致的结构还是一致的。

结构图取自 https://juejin.im/post/6844903661349371911

ApplicationContext继承了BeanFactory,都包含了getBean()的方法,然后AbstractRefreshableApplicationContext 实现了ApplicationContext接口。其实从这个结构图可以发现BeanFactory依然是作为Spring Core模块中的基础类而存在的。

BeanFactory 与 ApplicationContext 关系图

功能分析:

This section explains the differences between the BeanFactory and ApplicationContext container levels and the implications on bootstrapping.

You should use an ApplicationContext unless you have a good reason for not doing so, with GenericApplicationContext and its subclass AnnotationConfigApplicationContext as the common implementations for custom bootstrapping. These are the primary entry points to Spring’s core container for all common purposes: loading of configuration files, triggering a classpath scan, programmatically registering bean definitions and annotated classes, and (as of 5.0) registering functional bean definitions.

Because an ApplicationContext includes all the functionality of a BeanFactory, it is generally recommended over a plain BeanFactory, except for scenarios where full control over bean processing is needed. Within an ApplicationContext (such as the GenericApplicationContext implementation), several kinds of beans are detected by convention (that is, by bean name or by bean type — in particular, post-processors), while a plain DefaultListableBeanFactory is agnostic about any special beans.

For many extended container features, such as annotation processing and AOP proxying, the BeanPostProcessor extension point is essential. If you use only a plain DefaultListableBeanFactory, such post-processors do not get detected and activated by default. This situation could be confusing, because nothing is actually wrong with your bean configuration. Rather, in such a scenario, the container needs to be fully bootstrapped through additional setup.

以上是Spring官网对AppliationContext Or BeanFactory使用的说明,核心的意思就是说 ApplicationContext包含BeanFactory的所有功能,所以通常建议在普通BeanFactory上使用,除非需要对Bean处理的完全控制。 在ApplicationContext(例如GenericApplicationContext实现)中,按照惯例(即,按Bean名称或Bean类型(尤其是后处理器))检测到几种Bean,而普通的DefaultListableBeanFactory则与任何特殊的Bean无关。Application相对于BeanFactory有很多的拓展功能,例如注释处理和AOP代理,BeanPostProcessor扩展点是必不可少的。但是如果你使用的是DefaultListableBeanFactory,默认情况下不会检测和激活此类后处理器。 这种情况可能会造成混淆,因为xml中bean配置实际上并没有错。 而是在这种情况下,需要通过其他设置将容器完全自举。

spring 与 beanfactory 比较

总结:

ApplicationContext包含了其它使用Spring相关功能,BeanFactory则只是有操作Bean的基本方法。作为框架而言,ApplicationContxt更加符合开箱即用的特征。

猜你喜欢

转载自blog.csdn.net/qq_42773863/article/details/107714965