spring源码-BeanFactory接口详解(三)

ClassPathXmlApplicationContext顶级接口除了ResourceLoader 还包括BeanFactory,以下是BeanFactory的介绍!

BeanFactory接口

Spring的本质是一个bean工厂(beanFactory)或者说bean容器,它按照我们的要求,生产我们需要的各种各样的bean。在生产bean的过程中,需要解决Bean实例化时属性的依赖问题,才引入了依赖注入DI。同时作为IOC必备的数据结构!Spring将bean封装为了BeanDefinition 保存在BeanFactory的 map 中 ,Spring根据BeanDefinition 来进行对象的创建和管理,既然有bean的创建和管理,就必定涉及生命周期!因此对spring bean的生命周期的理解就显得十分重要!

BeanFactory接口位于源码 spring-beans包中

BeanFactory的官方注释机器翻译:

Bean 工厂实现应尽可能支持标准的 bean 生命周期接口。 全套初始化方法及其标准顺序是:
BeanNameAware 的setBeanName
BeanClassLoaderAware 的setBeanClassLoader
BeanFactoryAware 的setBeanFactory
EnvironmentAware 的setEnvironment
EmbeddedValueResolverAware 的setEmbeddedValueResolver
ResourceLoaderAware 的setResourceLoader (仅在应用程序上下文中运行时适用)
ApplicationEventPublisherAware 的setApplicationEventPublisher (仅在应用程序上下文中运行时适用)
MessageSourceAware 的setMessageSource (仅在应用程序上下文中运行时适用)
ApplicationContextAware 的setApplicationContext (仅在应用程序上下文中运行时适用)
ServletContextAware 的setServletContext (仅在 web 应用上下文中运行时适用)
BeanPostProcessors 的postProcessBeforeInitialization方法
InitializingBean 的afterPropertiesSet
自定义初始化方法定义
BeanPostProcessors 的postProcessAfterInitialization方法
在关闭 bean 工厂时,以下生命周期方法适用:
DestructionAwareBeanPostProcessors 的postProcessBeforeDestruction方法
DisposableBean的destroy
自定义销毁方法定义
在这里插入图片描述
继承体系:
请添加图片描述

接口中提供了抽象的bean获取方法以及部分bean判断的方法!

BeanFactory包含三个子接口和一个实现类:

1. ListableBeanFactory接口:
先看方法,可以获取Bean定义信息,与BeanFactory不同的是ListableBeanFactory包含的抽象方法都被定义为了可以返回多个Bean的方式! 也就是说这个接口是可以一下返回多个bean的抽象层!而获取父级工厂类的方法则被放到了HierarchicalBeanFactory中!
在这里插入图片描述
源码机器翻译:
BeanFactory接口的扩展,由可枚举其所有 bean 实例的 bean 工厂实现,而不是按照客户的要求逐一尝试通过名称查找 bean。 预加载所有 bean 定义的 BeanFactory 实现(例如基于 XML 的工厂)可以实现此接口。
如果这是一个HierarchicalBeanFactory ,则返回值不会考虑任何 BeanFactory 层次结构,而只会与当前工厂中定义的 bean 相关。 使用BeanFactoryUtils辅助类也可以考虑父工厂中的 bean。
该接口中的方法将只遵循该工厂的bean定义。 他们将忽略任何通过其他方式注册的单例 bean,例如 ConfigurableBeanFactory的registerSingleton方法,除了getBeanNamesForType和getBeansOfType ,它们也会检查这些手动注册的单例。 当然BeanFactory 的getBean也允许对这种特殊bean进行透明访问。 但是,在典型的场景中,无论如何,所有的 bean 都会被外部 Beandefinitions 定义,所以大多数应用程序不需要担心这种区分。
注意:除了getBeanDefinitionCount和containsBeanDefinition ,此接口中的方法不是为频繁调用而设计的。 速度可能很慢。

以下为ListableBeanFactory实现类的简要说明:
1.1 StaticListableBeanFactory:拥有addBean方法,允许以编程方式注册现有的单例实例,注册的bean会被保存在属性名叫beans的LinkedHashMap中!注意是管理现有 bean 实例!即管理beans这个LinkedHashMap中保存的bean,对其进行CRUD,所以说该工厂并不以BeanDefinition 的形式去创建bean实例!只是对保存在beans中的bean进行简单管理。

1.2 ApplicationContext:耳熟能详的接口,封装了spring的生命周期方法以及各种容器相关的配置方法!具体分析见后续文章内容链接:https://editor.csdn.net/md/?articleId=121400815

1.3 ConfigurableBeanFactory :这里首先介绍一下HierarchicalBeanFactory 的子接口,它为spring的内部工厂支持接口,继承了HierarchicalBeanFactory 和 SingletonBeanRegistry 这两个接口,也就是说同时继承了分层和单例bean注册的功能。实现对bean的注册配置,ConfigurableBeanFactory拥有String类型的属性“singleton”,和“prototype”,定义BeanFactory的配置,如类加载器,类型转化,属性编辑器,BeanPostProcessor,作用域,bean定义,处理bean依赖关系,合并其他ConfigurableBeanFactory,销毁指定作用域的bean,销毁单例Bean.根据bean定义销毁bean等!

这里值得注意的是Spring中 bean的各种作用域是怎么样实现的? spring的作用域:singleton、prototype、request、session、gloabSession。其中单例就是由SingletonBeanRegistry 接口完成单例Bean的注册。通过BeanDefinition完成定义。

	//BeanDefinition中的字段,对作用域的解析则有Spring 的一系列解析器进行读取存储和解析判断
	String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;
	String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;

```java
public interface SingletonBeanRegistry {
//在给定的beanName下,将现有的单例对象注册为Spring的单例
void registerSingleton(String beanName, Object singletonObject);
// 通过名称获取单例
@Nullable
Object getSingleton(String beanName);
//单例匹配
boolean containsSingleton(String beanName);
//获取单例名数组
String[] getSingletonNames();
//返回注册的单例Bean的数量
int getSingletonCount();
//返回单例的互斥锁,即返回保存了单例名称和实例对象的ConcurrentHashMap,该Map作为锁对象使用
Object getSingletonMutex();

}


**1.4 ConfigurableListableBeanFactory:** 继承了3个接口,ListableBeanFactory、AutowireCapableBeanFactory 和 ConfigurableBeanFactory。接口的自有方法总体上只是对父类接口功能的补充,包含了BeanFactory体系目前的所有方法,是接口的集大成者。以下是该工厂扩展的8个方法的介绍!
```java
	//忽略自动装配的依赖类型
	void ignoreDependencyType(Class<?> type);
	//忽略自动装配的接口
	void ignoreDependencyInterface(Class<?> ifc);	
	// 注册一个可分解的依赖
	void registerResolvableDependency(Class<?> dependencyType, @Nullable Object autowiredValue);
	//判断指定的Bean是否有资格作为自动装配的候选者
	boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)throws NoSuchBeanDefinitionException;
	//通过bean的名称返回注册的Bean定义
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	//获取bean名称的迭代器,具体实现需要见
	Iterator<String> getBeanNamesIterator();
	//清除合并的 bean 定义缓存,删除认为尚不符合完整元数据缓存条件的 bean 的条目。通常在更改原始 bean 定义后触发,例如在BeanFactoryPostProcessor 中PostProcessorRegistrationDelegate代理在执行invokeBeanFactoryPostProcessors方法的最后清理时会清理DefaultListableBeanFactory的singletonBeanNamesByType 、allBeanNamesByType、mergedBeanDefinitionHolders三个Map属性,当然也会清理一次都没有被创建的Bean定义即将 RootBeanDefinition中的stale变量重置为true,stale是用来确定Bean定义是否需要重新合并的。 请注意,此时已创建的 bean 的元数据将保留。
	void clearMetadataCache();
	//冻结所有 bean 定义,表明注册的 bean 定义不会被进一步修改或后处理。允许工厂积极缓存 bean 定义元数据,即冻结时按顺序排列的bean名称集合会被保存在DefaultListableBeanFactory的  frozenBeanDefinitionNames String数组属性中!
	void freezeConfiguration();
	//判断本工厂配置是否被冻结
	boolean isConfigurationFrozen();
	//实例化所有不是懒加载的单例Bean
	void preInstantiateSingletons() throws BeansException;

2. HierarchicalBeanFactory:
Hierarchical即分等级的,这个接口类仅仅只有两个方法:getParentBeanFactory 和 containsLocalBean 。很明显需要获取父工厂类的时候需要实现该接口!ApplicationContext和ConfigurableBeanFactory 均继承了该接口!

	//获取父级的bean工厂,没有返回null! 
	BeanFactory getParentBeanFactory();
	//返回本地 bean 工厂是否包含给定名称的 bean,忽略在祖先上下文中定义的 bean。
	//这是containsBean的替代方法,忽略来自父级bean工厂的给定名称的 bean。
	boolean containsLocalBean(String name);
	//需要知道的是ConfigurableBeanFactory中可以找到设置父级的 bean 工厂的相应setParentBeanFactory方法,而ConfigurableBeanFactory这个扩展接口只是为了允许框架内部的即插即用和对 bean 工厂配置方法的特殊访问。了解即可!

在这里插入图片描述

3. AutowireCapableBeanFactory:
很明显这是自动注入是需要使用的Bean工厂,包含了bean的创建、注入配置、属性设置、依赖解析、后置处理器前后的实例化、bean的实例化、bean的销毁等方法的一些列的抽象!
在这里插入图片描述
源码机器翻译:
BeanFactory接口的扩展将由能够自动装配的 bean 工厂实现,前提是它们希望为现有 bean 实例公开此功能。
BeanFactory 的这个子接口不打算在正常的应用程序代码中使用:对于典型用例,坚持使用BeanFactory或org.springframework.beans.factory.ListableBeanFactory 。
其他框架的集成代码可以利用这个接口来连接和填充 Spring 不控制其生命周期的现有 bean 实例。 例如,这对 WebWork Actions 和 Tapestry Page 对象特别有用。
请注意,此接口不是由org.springframework.context.ApplicationContext门面实现的,因为它几乎从未被应用程序代码使用过。 也就是说,它也可以从应用程序上下文中获得,可以通过 ApplicationContext 的org.springframework.context.ApplicationContext.getAutowireCapableBeanFactory()方法访问。
您还可以实现org.springframework.beans.factory.BeanFactoryAware接口,即使在 ApplicationContext 中运行时,它也会公开内部 BeanFactory 以访问 AutowireCapableBeanFactory:只需将传入的 BeanFactory 强制转换为 AutowireCapableBeanFactory
4. SimpleJndiBeanFactory:
此处提一下JNDI的概念:JNDI是 Java 命名与目录接口(Java Naming and Directory Interface),在J2EE规范中是重要的规范之一,没有JNDI我们切换数据库的话需要自己创建连接并解析需要改非常多的代码切换,有了JNDI规范以后可以分配置文件进行配置切换而不是修改代码进行切换!移植性提高了!维护性好了!SimpleJndiBeanFactory是 BeanFactory接口基于 JNDI 的简单实现。 不支持枚举 bean definitions,因此不实现ListableBeanFactory接口。
该工厂将给定的 bean 名称解析为 Java EE 应用程序的“java:comp/env/”命名空间中的 JNDI 名称。 它缓存所有获得的对象的解析类型,并且还可以选择缓存可共享对象(如果它们被显式标记为shareable resource)。
该工厂的主要目的是与 Spring 的org.springframework.context.annotation.CommonAnnotationBeanPostProcessor结合使用,配置为“resourceFactory”,用于将@Resource注释解析为 JNDI 对象,而无需中间 bean 定义。 当然,它也可以用于类似的查找场景,尤其是在需要 BeanFactory 样式的类型检查时。

而ClassPathXmlApplicationContext则实现了其中两个子接口:ListableBeanFactory、HierarchicalBeanFactory。因此ClassPathXmlApplicationContext拥有了获取bean工厂的父级工厂以及一下子获取一堆bean的能力!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

平塘码道

谢谢你的打赏, 我会继续努力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值