平常在使用的 Spring 的过程中,我想大家应该用到的都是 ApplicationContext 用来读取配置文件,然后启动 Spring 容器。但是,我们使用过程中,肯定也知道存在 Beanfactory 的存在。那么我们为什么都是使用 ApplicationContext,而非 Beanfactory 的那?
BeanFactory 获取 Bean
现在写个用 BeanFactory 来获取定义的 bean 程序。
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
BeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.loadBeanDefinitions(new ClassPathResource("applicationContext.xml"));
DemoServiceImpl demo = (DemoServiceImpl) beanFactory.getBean("demo");
复制代码
现在我们对比用 ApplicationContext 写一个获取 bean 的程序。
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DemoService demo = (DemoService) ctx.getBean("demo");
复制代码
从上面两个程序对比可以看出,使用 Beanfactory 来获取 Bean ,我们还额外实现相关类。这些类我们使用 ApplicationContext 根本无需实现。那么为什么是这样的那?接下去我们查看 Spring 相关的源码。
Spring 源码
上面两个程序我们看出 ApplicationContext 与 BeanFactory 都存在 getBean 这个核心方法。这个时候自然想到。这两个类是否实现了相同的接口。使用 Idea 类图功能,得到了下面了关系图。
从这个图中我们清晰看出 ApplicationContext 继承 BeanFactory,自然的 ApplicationContext 就拥有了 BeanFactory 的相关方法了。然后再看其实现类相关代码,画出下面一张类图。
从这张类图可以看出,AbstractRefreshableApplicationContext 存在的 Beanfactory 属性,我们再查看 ApplicationContext getBean 方法实际上最后委托 BeanFactory 的 getBean 方法。
综上,我们可以看出 Beanfactory 是 Spring 基础类,构造很多 Bean 相关的方法。然后 ApplicationContext 继承了 Beanfactory,封装了很多获取 Bean 细节方法,再扩展其他方法。这样我们使用者根本无需考虑相关细节,拿来就可以使用。下面图展示了两者相关功能区别。
两者比较看出,Beanfactory 其实只有基本只有跟 Bean 相关的功能。所以在实际开发中,我们使用 ApplicationContext 就可以使用相关 Spring 功能。如果使用 Beanfactory 其实也可以也实现这些功能,但是这个时候我们就需要知道其中很多相关细节。作为一个框架而言,其自然做到是开箱即用,而无需让使用者考虑其内部相关细节。所以 Spring 做了相关封装,最后成了我们经常使用的 ApplicationContext。