什么是BeanFactory?
Spring官网对BeanFactory的解释
BeanFactory API 为Spring的IoC功能提供了底层基础。它的特定契约主要用于Spring的其他部分以及相关第三方框架其他部分的集成,它的DefaultListableBeanFactory实现是更高级别GenericApplicationContext容器的一个委托。
BeanFactory和相关接口(例如BeanFactoryAware,InitializingBean,DisposableBean)是其他框架组件的重要集成点。不需要通过任何注解或甚至不需要反射,它们允许容器及其组件之间非常有效的交互。应用级别的bean可以使用相同的回调接口,但通常更偏好通过注解或通过程序配置进行声明式依赖注入。
请注意,核心BeanFactory API及DefaultListableBeanFactory实现不会假设要使用的配置格式或任何组件注解。这些都是通过扩展(例如XmlBeanDefinitionReader和AutowiredAnnotationBeanPostProcessor)引入的,并以核心元数据表示形式对共享的BeanDefinition对象进行操作。这就是使Spring的容器如此灵活和可扩展的本质。
BeanFactory源码注释
BeanFactory是用于访问Spring Bean容器的根接口,是bean容器的基本客户机视图;
其他接口,如ListableBeanFactory和ConfigurableBeanFactory可用于特定目的。
这个接口是由包含许多bean定义的对象实现的,每个bean定义都由一个字符串名称唯一标识。根据bean定义,工厂将返回包含对象的独立实例(原型设计模式)或单个共享实例(单例设计模式的高级替代方案,其中实例是工厂范围内的单例)。返回哪种类型的实例取决于bean工厂配置:API是相同的。自Spring2.0以来,根据具体的应用程序上下文(例如web环境中的“request”和“session”作用域),可以使用更多的作用域。
这种方式的要点是BeanFactory是应用程序组件的中心注册中心,它集成了应用程序组件的配置(例如,单个对象不再需要读取属性文件)。参阅“Expert One-on-One J2EE Design and Development”的第4章和第11章,以了解此方式的好处。
注意,通常最好依赖依赖注入(“push”配置)通过setter或构造函数配置应用程序对象,而不是像BeanFactory查找那样使用任何形式的“pull”配置。Spring的依赖注入功能是使用这个BeanFactory接口及其子接口实现的。
通常,BeanFactory将加载存储在配置源(如XML文档)中的bean定义,并使用org.springframework.beans包来配置bean。然而,实现可以直接在Java代码中返回它创建的Java对象。对于如何存储定义没有任何限制:LDAP、RDBMS、XML、属性文件等。鼓励实现支持bean之间的引用(依赖注入)。
与ListableBeanFactory中的方法相反,如果是HierarchicalBeanFactory,则接口中的所有操作也将检查父工厂。如果在此工厂实例中找不到bean,则会查询直接父工厂。工厂实例中的bean应该重写任何父工厂中同名的bean。 Bean工厂实现应该尽可能支持标准的Bean生命周期接口。
BeanFactory认识小结
Spring官方及源码中对BeanFactory进行了详细的解释,但是其中涉及了较多的概念,对于初学者来说,相对晦涩难懂,总结BeanFactory如下。
BeanFactory使用工厂方法的设计模式,作为一个工厂,它管理的对象被称为bean,bean可以是单例的,也可以是原型的,具体取决于bean定义。
BeanFactory并不关心bean的配置源来自何处,是何种格式,通过扩展最终都会被解析为BeanDefinition表示。
BeanFactory体系使用了分层设计的方式,BeanFactory是一个最基本的容器,Spring依赖注入功能是使用BeanFactory接口及其子接口实现的。
BeanFactory源码分析
BeanFactory作为基础的容器提供了很多获取bean信息的接口。
版本说明
源码使用的spring framework版本为5.2.6.RELEASE
BeanFactory类结构
BeanFactory字段
String FACTORY_BEAN_PREFIX = "&";
BeanFactory中仅包含一个名为FACTORY_BEAN_PREFIX的字段,获取bean时,如果bean名称以FACTORY_BEAN_PREFIX开头,并且bean的类型是FactoryBean,则表示要获取的bean是FactoryBean本身,而不是根据FactoryBean bean的实例获取的bean。
BeanFactory方法
获取bean实例的方法
Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; <T> ObjectProvider<T> getBeanProvider(Class<T> requiredType); <T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
getBean方法用于实时查找bean,getBeanProvider方法用于延迟查找bean。
涉及的字段含义如下:
name:表示要获取的bean的名称或别名,一个bean必须有一个唯一的名称标识,但可以有多个别名。
requiredType:表示要获取的bean的类型,获取的bean的实际类型可以是该类型或该类型的子类。
args:构造方法或工厂方法的参数。spring中的bean可以通过构造方法直接创建,也可以使用配置的工厂方法进行创建。
返回值:
Object:如果没有指定所需的bean的类型,则会返回Object类型。
T:如果指定了所需的bean的类型,则spring会把bean转换为所需的类型。
ObjectProvider<T>:可以理解为bean对象的提供者,可以根据这个类中的方法延迟获取bean。
异常:
BeansException:如果不能创建bean或者无法获取到bean则抛出该异常。
获取bean特性的方法
// BeanFactory是否包含给定名称或别名的bean boolean containsBean(String name); // 给定名称或别名的bean在BeanFactory中是否为单例或原型的,如果没有给定名称的bean则抛出异常 boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; // 给定名称的bean是否匹配给定的类型,如果没有给定名称的bean则抛出异常 boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;
这些方法主要用于获取BeanFactory中bean是否具有某一种特性。
获取类型和别名的方法
//获取给定名称的bean的类型,如果没有给定名称的bean则抛出异常,@Nullable说明返回值可能为null @Nullable Class<?> getType(String name) throws NoSuchBeanDefinitionException; //获取给定名称的bean的类型,allowFactoryBeanInit表示是否允许初始化FactoryBean以获取类型,如果没有给定名称的bean则抛出异常,@Nullable说明返回值可能为null @Nullable Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException; //获取给定名称的bean的别名 String[] getAliases(String name);
知识扩展
org.springframework.lang.Nullable:spring 5.0新增的注解,可以注解到成员变量,方法参数,方法上,表示被注解的元素的值可能为null。
ObjectProvider:ObjectFactory的子类,在ObjectFactory的基础上添加了根据条件获取bean对象以及获取多个bean对象的方法,可用于延迟查找bean。
ResolvableType:简化泛型处理的工具类,可以轻易的获取到泛型类中的泛型类型。
总结
BeanFactory作为最基础的容器提供了获取bean信息的方法,并未涉及到bean信息的来源、如何解析bean元信息、如何实例化、初始化、销毁等,这些将在后面的文章进行分析。