目录
一、BeanFactory
Spring 使用 BeanFactory 来实例化、配置和管理 Bean,它是IOC容器的核心接口,主要定义了getBean方法。
BeanFactory 只能管理单例(Singleton)Bean 的生命周期。它不能管理非单例Bean的生命周期,这是因为原型Bean实例被创建之后便被传给了客户端,容器失去了对它们的引用。
BeanFactory有着庞大的继承、实现体系,有众多的子接口、实现类。来看一下BeanFactory的基本类体系结构(接口为主):
BeanFactory最常见的实现类有 XmlBeanFactory 和 DefaultListableBeanFactory ,可以从classpath或文件系统等获取资源。
具体获取Bean代码如下(beans.xml文件和实体类代码自己写):
//通过资源加载器获取加载文件资源
ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource resource = resolver.getResource("beans/beans.xml");
System.out.println(resource.getURL());
//获取beanFactory二种方式
//方式一 XmlBeanFactory废弃,不建议使用
BeanFactory factory1 = new XmlBeanFactory(resource);
//方式二 DefaultListableBeanFactory
DefaultListableBeanFactory factory2 = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory2);
reader.loadBeanDefinitions(resource);
Car car = (Car)factory2.getBean("car");//第一次调用factory.getBean方法才会调用默认构造器生成实例
//spring在DefaultSingletonBeanRegistry类中提供了缓存单例bean,用HashMap实现的,以beanName为key进行保存,所以第二次get对象的时候不会调用构造器
Car car2 = (Car)factory2.getBean("car");
System.out.println(car==car2);//true,bean定义的默认是单例
总结:
1、XmlBeanFactory通过Resource装载Spring配置信息冰启动IoC容器,然后就可以通过factory.getBean从IoC容器中获取Bean了。
2、通过BeanFactory启动IoC容器时,并不会初始化配置文件中定义的Bean,初始化动作发生在第一个调用时。
3、对于单实例(singleton)的Bean来说,BeanFactory会缓存Bean实例,所以第二次使用getBean时直接从IoC容器缓存中获取Bean。
二、ApplicationContext(应用上下文)
ApplicationContext,也是接口,由BeanFactory派生而来,它继承了BeanFactory的基本功能,同时也扩展了部分功能。
在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置实现。
BeanFactory面向的是Spring框架,而ApplicationContext面向的是使用Spring框架的开发者。
相较于BeanFactorty,ApplicationContext提供了以下的功能:
(1)MessageSource, 提供国际化的消息访问
(2)资源访问,如URL和文件
(3)事件传播特性,即支持aop特性
(4)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
ApplicationContext的实现类主要有:
1、ClassPathXmlApplicationContext
配置文件放在类路径上
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans/beans.xml");
Car car = (Car)applicationContext.getBean("car");
2、FileSystemXmlApplicationContext
配置文件放在文件系统下
ApplicationContext ac = new FileSystemXmlApplicationContext("beans/beans.xml");
Car car2 = (Car)ac.getBean("car");
3、AnnotationConfigApplicationContext
@Configuration注解获取ApplicaitonContext方式
ApplicationContext ac = new AnnotationConfigApplicationContext(Car.class);
Car car2 = (Car)ac.getBean("car");
BeanFactroy与ApplicationContext的区别:
(实例化Bean的时机不同)BeanFactroy采用的是延迟加载形式来注入Bean的,即只有在使用到某个Bean时(调用getBean()),才对该Bean进行加载实例化,这样,我们就不能发现一些存在的Spring的配置问题。而ApplicationContext则相反,它是在容器启动时,一次性创建了所有的Bean。这样,在容器启动时,我们就可以发现Spring中存在的配置错误。 相对于基本的BeanFactory,ApplicationContext 唯一的不足是占用内存空间。当应用程序配置Bean较多时,程序启动较慢。
参考:https://www.cnblogs.com/xiaoxi/p/5846416.html