前言
你我在此相遇,全因八股文。
一年之后就要找实习了,所以我想提前储备好知识,希望被面试的时候不会被拷打死。本系列文章将会分享我探索Spring框架的经历与了解到的知识。
至此,既然逃不掉,那就使劲造。
以下是本文探讨的问题:
- BeanFactory与Application的区别?
- BeanFactory与Application的实现?
一.BeanFactory与ApplicationContext的区别?
1.它俩为何物?
BeanFactory顾名思义,Bean的加工厂,主要责任是对Bean进行实例化、配置和管理,并支持延迟初始化(支持在获取Bean时才进行实例化),提供了最简单的容器功能。
ApplicationContext-------应用上下文 ,是BeanFactory的子接口,由BeanFactory派生而来,是一个维护Bean定义以及对象之间协作关系的高级接口,能提供更多企业级功能。
两者同为Spring框架中的容器,而ApplicationContext继承了多个接口,相比BeanFactory拓展了更多实用功能,作为Spring核心容器的它起着不可或缺的功能。
我们先看到两者的继承关系
ApplicatonContext间接继承了BeanFactory
同时BeanFactory作为一个简单功能的容器,体现有二。
其一,我们可以在SpringApplication.run方法生成
ConfigurableApplicationContext的一个实现类中AbstractApplicationContext的getBean方法得知其底层是获取BeanFactory对象调用其中getBean方法的。
其二,DefaultListableBeanFactorys实现了BeanFactory,作为ApplicationContext属性的同时 ,设置了一个类型为ConcurrentHashMap的属性来保存所有单例Bean
遍历结果
编辑
2.区别
BeanFactory作为古老的Factory提供了IOC(控制反转:将对象控制权的转移,从程序代码本身反转到了外部容器。 把对象的创建、初始化、销毁等工作交给容器来做。)和DI(依赖注入)功能,但是却无法支持spring插件,例如:AOP、Web应用等功能。
当我们使用BeanFactory去获取Bean的时候,我们只是实例化了该容器,而该容器中的bean并没有被实例化。当我们getBean的时候,才会实时实例化该bean对象,俗称懒加载
BeanFactory接口的一些常见实现类包括DefaultListableBeanFactory和XmlBeanFactory。
除了提供BeanFactory的所有功能,ApplicationContext还提供了更多的企业级特性,如AOP(面向切面编程)、事件发布、国际化、资源加载、Bean生命周期管理、安全性等
事件发布与监听
当我们使用ApplicationContext去获取bean的时候,是会预先创建好所需要的bean的
二.BeanFactory与ApplicationContext的实现?
BeanFactory的实现
创建BeanFactory对象——>做bean的定义(class,scope,初始化,销毁)——>注册bean
——>为BeanFactory添加常用处理器以及设置比较器(用来解析注解,比如@Bean,@Configuration)——>使后处理器工作——>补充后处理器
注:第一个添加常用处理器只是把一些后处理器加入到了BeanFactory,只是存在于BeanFactory中的一个bean而已,还没建立联系,第二个是加上BeanFactory和后处理器的联系,才能告诉BeanFactory每个bean创建后,需要哪些后处理器。
DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
//定义
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition(Config.class).
setScope("singleton").getBeanDefinition();
//注册
beanFactory.registerBeanDefinition("config",beanDefinition);
//为BeanFactory提供一些常用处理器
//此外还设置了比较器
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//根据一个类型获取多个Bean,使其工作,扩展
beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().stream().forEach(beanFactoryPostProcessor -> {
System.out.println(beanFactoryPostProcessor);
beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
});
System.out.println("