阅读 Spring 源码,BeanFactory 是避不了的存在。而大家常见的使用场景,也是以下形式:
ConfigurableApplicationContext ctx = SpringApplication.run(xxx.class);
BeanFactory beanFactory = (BeanFactory) ctx;
beanFactory.getBean(xxx);
但 BeanFactory 可不是如此枯燥无味的。
在 Spring 中 BeanFactory 接口的定义非常简单,主要有以下方法:
<T> T getBean(Class<T> requiredType) throws BeansException;
boolean containsBean(String name);
boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
String[] getAliases(String name);
// ...其他
只负责获取、判断操作。
然而,仅仅这些方法并不满足多功能 BeanFactory 的需求,所以 BeanFactory 有以下三个不同特性的子类:
ListableBeanFactory
HierarchicalBeanFactory
AutowireCapableBeanFactory
String[] getBeanDefinitionNames();
boolean containsBeanDefinition(String beanName);
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType) throws NoSuchBeanDefinitionException;
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType, boolean allowEagerInit);
BeanFactory getParentBeanFactory();
boolean containsLocalBean(String name);
常见的 Bean 的实例化的过程
在此工厂中完成,定义了相关的 API)<T> T createBean(Class<T> beanClass) throws BeansException; // 创建
void autowireBean(Object existingBean) throws BeansException; // 自动装配
Object initializeBean(Object existingBean, String beanName) throws BeansException; // 初始化
Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) BeansException; // 过程回调
Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException; // 过程回调
void destroyBean(Object existingBean); // 销毁
乍一看,发现 BeanFactory 丰富了很多,与 BeanDefinition 也有了关联,可仔细一看,就会发现,这些接口定义的都是获取或判断方法,与 BeanFactory 类似;而且都是与 Bean 有紧密联系。在此之外,Spring 提供了 BeanFactory 的相关控制选项的配置接口。
Spring 首先提供了一个 HierarchicalBeanFactory 的子类:ConfigurableBeanFactory。它定义了 BeanFactory 的一些相关配置入口,同时也定义了 HierarchicalBeanFactory#getParentBeanFactory 的parent设置入口,总的来说,它是 BeanFactory 配置的相关类(定义了配置的设置与获取),比如有:Scope 的注册、类型转换器列表的持有,后置处理器的新增等等,
void setParentBeanFactory(BeanFactory parentBeanFactory) throws IllegalStateException; // 设置父工厂
void setBeanClassLoader(@Nullable ClassLoader beanClassLoader); // 设置 Bean 的 ClassLoader
void addBeanPostProcessor(BeanPostProcessor beanPostProcessor); // 添加 BeanPostProcessor
void registerScope(String scopeName, Scope scope); // 注册 Scope
Scope getRegisteredScope(String scopeName); // 从 BeanFactory 获取配置的 Scope 信息
BeanDefinition getMergedBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 获取合并后的 BeanDefinition
工厂相关的配置有了。Spring 又在此基础上,扩展了一个新的子工厂类型:ConfigurableListableBeanFactory,它的继承关系如下:
此接口继承了所有 BeanFactory 相关的主要接口类型,具备了上述提及的工厂的所有功能,现在这个类型是“有闲有钱”,我们来看看它定义了哪些新方法:
void ignoreDependencyInterface(Class<?> ifc); // 忽略依赖接口,如:Aware 类接口
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException; // 获取Bean定义(只获取当前Bean内的定义,不考虑层级)
boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor) throws NoSuchBeanDefinitionException; // 是否支持自动注入
void freezeConfiguration(); // 冻结配置,Bean定义不再支持修改(修改意味着要重新生成Bean实例)
void preInstantiateSingletons() throws BeansException; // 与实例化所有单例
因为继承了自动配置工厂(AutowireCapableBeanFactory),因此具备自动装配Bean能力。同时自己在此基础上,定义了一层外部控制,如:isAutowireCandidate、freezeConfiguration,更重要的是:preInstantiateSingletons。
毕竟它现在掌握了资源:具备检索Bean定义、具备自动装配控制、具备Bean工厂配置,因此它有能力作为实例化单例的入口。
除了继承主要的 Bean工厂类型,此接口还继承了 SingletonBeanRegistry
。此接口与其他接口没有任何关联,却与 Spring IOC 特性息息相关。
我们知道,Spring 容器中的 Bean 具备多种 Scope 范围,我们常见的是 Singleton、Prototype。但通过以上工厂定义,我们看到的只有 getBean 操作,而没有 getSingleton。也就是说:Spring 的顶层 BeanFactory 关注的的确只有 IOC(即控制反转),而不关注容器内是单例还是原型。要想通过 BeanFactory 来获知实例范围信息,只能通过其方法:isSingleton
,isPrototype
。没错,就是这么纯粹。
因为单例模型在Spring中也是举足轻重,所以 Spring 划分了单独的概念:SingletonBeanRegistry
它的方法有:
void registerSingleton(String beanName, Object singletonObject); // 注册单例(不一定要通过Bean定义构建)
Object getSingleton(String beanName); // 获取单例
boolean containsSingleton(String beanName); // 判断是否包含单例
String[] getSingletonNames(); // 获取所有单例名称
int getSingletonCount(); // 获取单例数
具备了单例的注册与获取。
当然,除非明确指定 bean 非单例,否则,在 Spring 中默认解析 Bean定义后注册到容器中,都是使用:registerSingleton
,即默认注册单例类型。
以上结果,构建了一个功能丰富且完善的 Bean工厂,具有
每个 Bean工厂都有相应的 Abstract实现,最终由子类:DefaultListableBeanFactory 完成统一大业,并被 ApplicationContext 使用
Bean 的构建基于 Bean定义,它从何而来?
Spring 为 BeanDefinition 定义了抽象 BeanDefinitionRegistry
,具有以下方法:
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException;
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
boolean containsBeanDefinition(String beanName);
String[] getBeanDefinitionNames();
int getBeanDefinitionCount();
boolean isBeanNameInUse(String beanName);
具备 Bean定义的注册、移除、获取、判断等,并由 DefaultListableBeanFactory 进行实现。所以 DefaultListableBeanFactory 作为 Spring 的核心类 ApplicationContext 的内定工厂,实现如下:
总结:
了解了 BeanFactory 的继承体系之后,你能够很快地回忆起相关的知识点,比如:
AutowireCapableBeanFactory
中,而且默认实现就是抽象类:AbstractAutowireCapableBeanFactory
;如何较好地记忆 BeanFactory 相关知识点,可通过功能、命名等方面入手,如:
回顾源码,你会看到如下代码
只有相应的接口实现,才具备对应的 API 进行设置与获取。
以上是 Bean工厂的相关学习与总结,如果错漏,欢迎指正。
【Spring浅析】一、 BeanFactory 有啥可说的?
原文:https://www.cnblogs.com/gcexceeded/p/14774334.html