从面相对象的抽象能力讲spring的设计
2021-11-06 08:44:08 0 举报
AI智能生成
登录查看完整内容
spring的BeanFactory,applicationContext等类图有很多,spring启动过程分析也很多。但经常迷失在其中,找不到方向。本文从抽象能力依次分解spring的层次关系。从抽象到具象来理解那些ApplicationContext各自的职责。
作者其他创作
大纲/内容
获取Bean,是否包含Bean等Bean的一些能力抽象
Bean是一个具体业务对象,因此没有用专门的类来描述bean
但从一些判断接口可以发现:bean有是否单例SCOPE、有别名等特性
BeanFactory
是否包含bean,bean的个数,所有beanName的数组等集合的特性
还包含了3个注解的接口,说明spring在往注解上发展
ListableBeanFactory
层级的关键体现
BeanFactory getParentBeanFactory()
这里是一个工具接口,区分与标准的包含Bean
boolean containsLocalBean(String name)
HierarchicalBeanFactory
factory.config包中,一种支持
AutowireCapableBeanFactory
void ignoreDependencyType(Class<?> type)
void ignoreDependencyInterface(Class<?> ifc)
忽略自动注入系列
指定注入
registerResolvableDependency
BeanDefinition getBeanDefinition(String beanName)
BeanDefinition
boolean isConfigurationFrozen()
void freezeConfiguration()
加载非延迟单例bean
void preInstantiateSingletons()
ConfigurableListableBeanFactory
ConfigurableBeanFactory
可配置
Environment
MessageSource
ApplicationEventPublisher
ResourcePatternResolver
支持其他特性
id,name,启动时间等
本身是可描述的实例,有生命周期
支持层级,getParent
不太典型的一些应用场景,先不管
AutowireCapableBeanFactory getAutowireCapableBeanFactory()
自己还描述了一些抽象能力
ApplicationContext
配置id
配置parent
配置Environment
添加BeanFactoryPostProcessor
添加ApplicationListener
添加ProtocolResolver
什么叫可配置
配置变化了,需要更新
refresh()
registerShutdownHook()
close()
isActive()
生命周期
所以,用的是组合的方式来实现BeanFactory的
什么叫可配置,该context是有生命周期的,但却可以配置来修改。调用refresh方法,来更新内部BeanFactory,从而提供不一样的Bean工厂
ConfigurableListableBeanFactory getBeanFactory()
ConfigurableApplicationContext
绕不开的web项目
包括扩展了bean的web生命周期scope_*
声明了一些常量
ServletContext getServletContext()
WebApplicationContext
来看看它具象了什么,抽象了什么
直接继承了解析资源的能力
spring应用程序运行时扩展全部从配置资源而来
extends DefaultResourceLoader
implements ConfigurableApplicationContext
也是个Bean。先有鸡还是蛋?
implements DisposableBean
applicationContext的第一个抽象类
active
closed
shutdownHook
destroy()
void close()
void start()
void stop()
boolean isRunning()
lifecycleProcessor
id
parent
ConfigurableEnvironment
resourcePatternResolver
environment
beanFactoryPostProcessors
可配置性
applicationEventMulticaster
applicationListeners
earlyApplicationEvents
publishEvent
概要
国际化
messageSource
refresh的大部分方法都用了pretected访问级别
标准的模板方法模式,同时支持子类扩展
获取一个beanFactory
配置这个beanFactory
执行非延迟加载单例bean
基本定义了一个applicationContext加载过程
<T> T getBean(Class<T> requiredType)
boolean containsBean(String name)
boolean isSingleton(String name)
boolean isPrototype(String name)
...
Object getBean(String name)
int getBeanDefinitionCount()
String[] getBeanDefinitionNames()
String[] getBeanNamesForType(ResolvableType type)
boolean containsBeanDefinition(String beanName)
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType)
具象
abstract void refreshBeanFactory()
abstract void closeBeanFactory()
abstract ConfigurableListableBeanFactory getBeanFactory()
抽象
抽象了加载BeanDefinition的方法
AnnotationConfigWebApplicationContext
GroovyWebApplicationContext
XmlWebApplicationContext
ClassPathXmlApplicationContext
FileSystemXmlApplicationContext
这就是为什么最终实现类是一些加载位置的命名
反过来说:AbstractApplicationContext具象了什么?bean实例化具象了没有?
抽象了什么?
createEnvironment()
prepareRefresh()
initPropertySources()
ConfigurableListableBeanFactory obtainFreshBeanFactory()
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
引出问题:现在beanFactory有了,在做些注入准备。现在有bean了没有?有什么?
void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory)
子类注入BeanDefinition
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
加工BeanDefinition
invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
注入Bean处理器
bean肯定还没加载
void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory)
void initMessageSource()
初始化事件广播器
void initApplicationEventMulticaster()
void initLifecycleProcessor()
注入事件监听器
void registerListeners()
beanFactory.preInstantiateSingletons();
其实是委托给内部那个beanFactory来实现的
这里就有no lazy bean加载的过程
void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory)
只做了几个生命周期事件处理和事件发布
void finishRefresh()
void doClose()
void destroyBeans()
可扩展
AbstractApplicationContext
DefaultListableBeanFactory
可以看到他的实现只做了loadBeanDefinition等,所以BeanFactory在上一层抽象中已经完成
最终一直抽象到AbstractRefreshableApplicationContext
与之对应的另外一层抽象GenericApplicationContext
分别看看几个关键的ApplicationContext子类获取的BeanFactory是哪个实现
另一个话题,处理BeanFactory不一样了
都用了DefaultListableBeanFactory
相同点:
不同点是什么?
ConfigurableListableBeanFactory的实现来看bean装载
体现出刷新,调用则删除重建
loadBeanDefinitions(beanFactory)
AbstractRefreshableApplicationContext
构造的时候构造了BeanFactory
且不允许刷新
void removeBeanDefinition(String beanName)
但提供了注入BeanDefinition的方法
据说更灵活的bean管理办法,且在cloud中有发挥作用
GenericApplicationContext
BeanFactory处理差异
构造
void scan(String... basePackages)
AnnotationConfigApplicationContext
GenericApplicationContext子类是如何loadBean的
BeanDefinition Loader
中间子类对BeanFactory的处理方式不一样,形成了不同的继承链
但对具体load bean加载方式,用组合的方式,都是依赖于Reader和Scan来完成加载
setInitializers
setListeners
把environment和listeners等绑定到context上
prepareContext
((AbstractApplicationContext) applicationContext).refresh()
refreshContext
用SpringApplication启动一个spring应用
默认内置了些
getSpringFactoriesInstances
从哪里来的
SpringApplicationRunListeners
starter包原理
dao层接口bean注入方法
AOP动态代理注入方法
springboot做了什么
扩展了refresh方法吗?没有
属于哪个步骤做的事情?
这个过程中能用spring技术吗?
扩展出来了一个boostrap.*的配置,怎么做到的?
config是怎么读取外部配置的,什么时机?
springcloud扩展了context的标准?
特点是:封装、继承、多态
抽象是的能力,有什么,能做什么
实现的是怎么做
抽象能力
核心能力:
面向对象
该文档没有详细讲解IOC等内容,只从抽象层次上将spring做的事情分解开
有了这张地图,下面springboot和springcloud中的几个知识点应该很容易找到地方并分解开
文档说明
从BeanFactory到ApplicationContext的抽象能力分析
到这里都只定义了接口
从这些接口我们已经看到spring给我们定义的Bean,BeanFactory,Context是什么了
web
事件
Message
并且有几个扩展和特性
BeanFactory扩展到List、支持层级
ApplicationContext也支持层级parent
applicationContext通过持有BeanFactory提供bean,bean支持扩展性
基本的结构
0 条评论
回复 删除
下一页