上篇Resource还比较简单,发现一到BeanFactory开始突然复杂起来,好像迷宫出现了很多的分支,每个分支又有又有非常多的分支,有点无从下手。目前大概思路是,主线还是跟着书走,搞清楚整体流程,在搞清整体流程之前先整理类的大概结构,这是次要任务,在整理过程中,如果遇到不是很深的知识点看情况补充,如果遇到好别的参考资料但是又不容易深入,收集成链接,也许在未来主线上会遇到,可以回头细致读。
先看XmlBeanFactory,这个类已经过期,一般用ApplicationContext,但是这个类简单一些,先作为入口吧。关于二者区别参考 Spring中BeanFactory和ApplicationContext的区别
下面是类图,可以看出,因为java单一继承的缘故,只有蓝色一条线是继承,剩下的都是实现,那么为什么继承是走的 aliasRegistry这条线呢?还有,已经有了SimpleAliasRegistry实现了接口,为什么还要 有Bean efinitionRegistry接口,先留做疑问吧,也许后面能搞清楚
BeanFactory,看下类的介绍是怎么说:访问bean容器的根接口,有子接口ListableBeanFactory和ConfigurableBeanFactory以适用于不同的目的。这个接口的实现持有一定数量的bean的定义,factory会返回一个独立的实例(prototype模式)或者一个单例(比单例模式高级,单例是在工厂范围内的单例)。实现的方式是beanfactory作为应用程序组件和配置的的中心注册表(registry),多数情况依赖注入(DI)是更好的方式,BeanFactory从配置源载入bean的定义,然后用beans包下的类来装配bean(通常是xml),但也可能从编码中直接载入配置,并不限制bean储存形式。相较于ListableBeanFactory,HierarchicalBeanFactory会检查父工厂,如果bean在本工厂未找到,则在直接父工厂找,子工厂的bean会覆盖父工厂的bean。BeanFactory的子类应当尽可能的支持标准的生命周期。注释里太长下面这段直接复制自 https://blog.csdn.net/onupway/article/details/80156240 (这篇文章给的是高版本的,比我读的源码多了点东西,顺序大体一致)
标准的初始化方法及其顺序是:
- BeanNameAware类的setBeanName方法调用
- BeanClassLoaderAware类的setBeanClassLoader方法调用
- BeanFactoryAware类setBeanFactory方法调用
- EnvironmentAware类setEnvironment方法调用
- EmbeddedValueResolverAware类setEmbeddedValueResolver方法调用
- ResourceLoaderAware类setResourceLoader方法调用(仅在ApplicationContext下才会调用)
- ApplicationEventPublisherAware类setApplicationEventPublisher方法调用 (仅在ApplicationContext下才会调用)
- MessageSourceAware类setMessageSource方法调用 (仅在ApplicationContext下才会调用)
- ApplicationContextAware类setApplicationContext方法调用 (仅在ApplicationContext下才会调用)
- ServletContextAware类setServletContext方法调用 (仅在WebApplicationContext下才会调用)
- BeanPostProcessor类postProcessBeforeInitialization方法调用
- InitializingBean类afterPropertiesSet方法调用
- 自定义初始化方法调用init-method
- BeanPostProcessor类postProcessAfterInitialization方法调用
可以观察到,前面几个都是Aware开头的,一般awarexx就是注入对xx的引用,比如BeanNameAware,自己实现这个接口后,再在内部用一个变量保存beanName,由框架调用set方法来注入属性。后置处理器,有点像AOP,是通用处理方法。然后中间InitializingBean接口为bean提供了初始化afterPropertiesSet方法,继承该接口的类,在初始化bean属性注入完成之后的时候会执行该方法。以上aware跟实现接口,都在一定程度上跟spring耦合,最后,可以使用Spring提供的init-method的功能来执行一个bean自定义的初始化方法,这个方法在xml中是定义成bean的属性,用注解的话可以用@PostConstruct代替。
Bean容器关闭的时候,销毁方法流程如下:
- DestructionAwareBeanPostProcessor类postProcessBeforeDestruction方法调用
- DisposableBean类的destroy方法调用 --对应的是 InitializingBean
- 自定义销毁方法destroy-method调用
生命周期参考以下文章
Spring Bean的生命周期 、Spring Bean的生命周期(非常详细) 、及 深入理解spring生命周期与BeanPostProcessor的实现原理
ListableBeanFactory: 它可以枚举所有的bean实例,而不是客户端通过名称一个一个的查询得出所有的实例,要一次性加载实例的工厂实现这个接口。可以观察到内部的方法基本上都是关于Beandefinition的,注意,其中的getBeanNamesForType方法 。仅检查顶级bean.它不会检查嵌套的bean.FactoryBean创建的bean会匹配为FactoryBean而不是原始类型。一样不会考虑父factory中的bean。非要用可以通过BeanFactoryUtilsbean
HierarchicalBeanFactory: 提供父容器的访问功能,如果同时实现了HierarchicalBeanFactory,返回值不会考虑父类BeanFactory,只考虑当前factory定义的类.当然也可以使用BeanFactoryUtils辅助类来查找祖先工厂中的类。
AutowireCapableBeanFactory :添加autowire功能。注释里说这个类是其他框架的扩展点,不知道为什么。提前看了下在新的ApplicationContext没有相关类。
ConfigurableBeanFactory:定义BeanFactory的配置。https://blog.csdn.net/u013412772/article/details/80819398
详细的看这篇文章,讲的很细Spring源码解析 - BeanFactory接口体系解读 ,源码里的注释都翻译好了,如果都这么细致自己都不用写笔记了,直接贴链接就行
其他参考文章
Spring点滴五:Spring中的后置处理器BeanPostProcessor讲解
Spring中BeanPostProcessor与InitializingBean接口的关系与应用
深入理解spring生命周期与BeanPostProcessor的实现原理