Spring IOC初始化
2021-09-09 08:35:48 0 举报
Spring IOC容器初始化过程
作者其他创作
大纲/内容
DeanDefinitionReader
postProcessBeanFactory(beanFactory)
准备工作
实例化对象
BeanFactory的setBeanFactory()方法
Environment
BeanPostProcessor
将A实例放入三级缓存singletonFactories
没有被创建中
Bean定义注册表
ClassLoader getBeanClassLoader();
getBeanFactory()AbstractRefreshableApplicationContext
prepareRefresh()AbstractApplicationContext
postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
LoadBeanDefinitions(beanFactory)AbstractXmlApplicationContext
读取
发现B中依赖A
BeanWrapper
boolean isPrototype(String name)
BeanPostProcessor的postProcessAfterInitialization()方法
将提前暴露的实例A设置到实例B中的属性中
BeanDefinitionRegistry getRegistry();
BeanNameAware的setBeanName()方法
int loadBeanDefinitions(Resource... resources)
boolean acceptsProfiles(Profiles profiles);
加载
1、初始化此上下文的转换服务2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。3、初始化LoadTimeWeaverAware Bean实例对象4、冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了5、实例化所有剩余(非懒加载)单例对象
配置类
注册监听器
spring中并没有具体去实现postProcessBeanFactory方法,是提供给想要实现BeanPostProcessor的三方框架使用的。谁要使用谁就去实现。作用是在BeanFactory准备工作完成后做一些定制化的处理,一般结合BeanPostProcessor接口的实现类一起使用,注入一些重要资源(类似Application的属性和ServletContext的属性)。最后需要设置忽略这类BeanPostProcessor子接口的自动装配。
容器启动过程
resetCommonCaches();
读取配置文件接口
ResourceLoader
创建提前暴露的B实例
new
BeanDefinitionReader
Spring IOC循环依赖(A依赖B,B依赖A)
此处并不是重要的方法,这个方法获取系统时间,设置相应的属性,验证标记为所需的所有属性都是可解析的,初始化earlyApplicationListeners、earlyApplicationEvents等等,如同方法名字,仅仅只是为环境更新做准备。
将B放入一级缓存singletonObjects并且删除二、三级缓存
PropertyEditorRegistry
boolean isSingleton(String name)
setConfigLocations(configLocations)AbstractRefreshableConfigApplicationContext
InitializingBean的afterPropertiesSet
Bean 的加载过程
BeanFactoryPostProcessor
从二级缓存earlySingletonObjects中获取A实例
invokeBeanFactoryPostProcessors(beanFactory)
所有属性编辑器的Bean
String FACTORY_BEAN_PREFIX = \"&\";
Bean属性的设置提供了很多以Java反射机制操作Bean的方法
doRegisterBeanDefinitions(Element root)DefaultBeanDefinitionDocumentReader
FactoryBean
1、setConfigLocations主要工作有两个:创建环境对象ConfigurableEnvironment 、处理ClassPathXmlApplicationContext传入的字符串中的占位符;2、环境对象ConfigurableEnvironment中包含了当前JVM的profile配置信息、环境变量、 Java进程变量;3、处理占位符的关键是ConfigurableEnvironment、PropertyResolver、PropertyPlaceholderHelper之间的配合
从singletonObjects中获取实例A
实例化
<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);
Class<?> getObjectType();
通过init-method属性配置初始化方法
工厂方法
加工后的BeanDefinition
1、首先,hasBeanFactory,判断context目前是否持有bean factory,如果有:先执行一个模版方法,销毁这个context管理的所有bean,默认实现销毁所有context中的单例缓存,调用DisposableBean.destroy()和/或特定的\"destroy-method\";再closeBeanFactory,即设置beanFactory的id为null,beanFactory为null。2、然后,createBeanFactory,为context创建一个internal bean factory。每次refresh()都会被调用,默认实现创建一个以context的getInternalParentBeanFactory()-parent为parent bean factory的org.springframework.beans.factory.support.DefaultListableBeanFactory,子类可以重写此方法来自定义DefaultListableBeanFactory的设置。3、然后,将context的id设置为beanFactory的SerializationId。4、然后,customizeBeanFactory,自定义beanFactory。自定义context的nternal bean factory,每次refresh()都会被调用,默认实现设置了context的setAllowBeanDefinitionOverriding \"allowBeanDefinitionOverriding\"以及setAllowCircularReferences \"allowCircularReferences\",子类可以重写此方法来自定义DefaultListableBeanFactory的设置。5、然后,loadBeanDefinitions,加载BeanDefinitions。通过XmlBeanDefinitionReader加载bean definitions。先用BeanFactory创建一个新的XmlBeanDefinitionReader;设置beanDefinitionReader的environment为contextd的resource loading environment;设置beanDefinitionReader的ResourceLoader为context;创建ResourceEntityResolver(this)并设置为beanDefinitionReader的EntityResolver;initBeanDefinitionReader,供子类覆写的方法,初始化beanDefinitionReader,默认为空实现;loadBeanDefinitions,用指定的XmlBeanDefinitionReader加载bean definitions,bean factory的生命周期由refreshBeanFactory方法处理,因此,这个方法只加载和/或注册bean definitions,委托ResourcePatternResolver解析location patterns到Resource实例,先获取configLocations,再调用XmlBeanDefinitionReader的loadBeanDefinitions方法完成beanDefinitions的加载。
没有获取到
InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法
开始创建B实例
Bean的实例化
spring容器
<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);
加载BeanDefinition入口
设置A实例的属性
Annotation
发现A中依赖B
Bean生命周期
singleton
BeanDefinitionParserDelegate对象
InstantiationStrategy
InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation()方法
refresh()AbstractApplicationContext
default boolean isSingleton() {return true;}
web.xml
String[] getDefaultProfiles();
完成上下文的刷新工作1、为此上下文初始化生命周期处理器2、首先将刷新完毕事件传播到生命周期处理器3、推送上下文刷新完毕事件到相应的监听器
实例化Bean的前置处理器
Bean实现类
BeanFactoryPostProcessor1、对bean的定义信息进行人为修改2、自动装配
从singletonObjects中获取实例B
destroyBeans();
后续加工
容器销毁
对BeanDefinition进行加工处理使用到占位符的<bean>元素标签进行解析
实例化Bean的后置处理器
构建BeanFactory入口
将A放入一级缓存singletonObjects并且删除二、三级缓存
BeanFactory
Bean信息
ServletContext
二级缓存没有
从三级缓存singletonFactories中获取A实例
BeanFactory的预准备工作1.设置类加载器;2.设置EL表达式解析器(Bean创建完成填充属性时使用)和属性注册解析器(PropertyEditor)3.利用BeanPostProcessor的特性给各种Aware接口的实现类注入ApplicationContext中对应的属性4、设置各种Aware接口的实现类为忽略自动装配5、设置自动装配的类(BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext)6、如果BeanFactory中存在loadTimeWeaver的bean,那么需要添加动态织入功能7、注册各种可用组件(environment,systemProperties,systemEnvironment)
检查A是否被创建中(singletonsCurrentlyInCreation)
保存
XML
Spring IOC 初始化核心流程
initMessageSource()
ClassPathXmlApplicationContext、FileSystemApplicationContext
prototype
boolean acceptsProfiles(String... profiles);
总结:保证高内聚、低耦合、扩展性Spring提供的扩展性?1、在对象创建之前添加某些功能2、在容器初始化之前添加某些功能3、在不同的阶段发出不同的事件,完成一些功能4、抽象出一堆的接口来帮助扩展5、面向接口编程
DispatcherServlet
应用程序
getBean()
对Bean进行封装
注册 BeanPostProcessor
完整的实例B
设置B实例的属性
String[] getActiveProfiles();
BeanDefinition
注解
Spring IOC的初始化过程
BeanPostProcessor的postProcessBeforeInitialization()方法
通过destroy-method配置销毁方法
实例创建结束
Resource
用于解析Xml配置文件
将B实例放入三级缓存singletonFactories
用做扩展
xxx.propertiesxxx.ymlSystem.getProperty()
解析Xml文件入口
Bean缓存池
初始化应用的事件广播器
IOC容器
标记B为正在创建中
Class<?> getType(String name)
onRefresh()
备注说明
创建提前暴露的A实例
XmlBeanDefinitionReader(beanFactory)
ResourceLoader getResourceLoader();
spring mvc容器
AbstractBeanDefinition
WebApplicationContext
检查B是否被创建中(singletonsCurrentlyInCreation)
int loadBeanDefinitions(String... locations)
其他
把A实例放入二级缓存earlySingletonObjects,并且删除三级缓存singletonFactories
Object getBean(String name)
initApplicationEventMulticaster()
BeanNameGenerator getBeanNameGenerator();
xml配置
放入容器
清除B正在创建的标记singletonsCurrentlyInCreation
T getObject()
解析得到document对象
registerListeners()
实例化Bean
Spring 容器
web容器
通过getBean()获取对象
将准备就绪的bean交给调用者
可以返回bean的实例的工厂bean,通过实现该接口可以对bean进行一些额外的操作,例如根据不同的配置类型返回不同类型的bean,简化xml配置等。在使用上也有些特殊,BeanFactory接口中有一个字符常量String FACTORY_BEAN_PREFIX = \"&\"; 当我们去获取BeanFactory类型的bean时,如果beanName不加&则获取到对应bean的实例;如果beanName加上&,则获取到BeanFactory本身的实例;FactoryBean接口对应Spring框架来说占有重要的地位,Spring本身就提供了70多个FactoryBean的实现。他们隐藏了实例化一些复杂的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型。
初始化B实例
Constructor con = clazz.getConstructor();Object obj = con.newInstance();
BeanDefinitionRegistry
设置属性值
boolean containsBean(String name);
refreshBeanFactory()AbstractRefreshableApplicationContext
初始化入库
清除A正在创建的标记singletonsCurrentlyInCreation
BeanDefinitionHolder
<T> T getBean(Class<T> requiredType)
obtainFreshBeanFactory()AbstractApplicationContext
监听器
1.拿到当前应用上下文 beanFactoryPostProcessors 变量中的值2.实例化并调用所有已注册的 BeanFactoryPostProcessor
int loadBeanDefinitions(String location)
资源定位
String[] getAliases(String name);
String OBJECT_TYPE_ATTRIBUTE = \"factoryBeanObjectType\";
开始创建A实例
BeanPostProcessor1、在bean实例化过程、增强某些功能2、AOP操作
DisposableBean的destroy()方法
int loadBeanDefinitions(Resource resource)
finishRefresh();
spring缓冲池中准备就绪的Bean
初始化A实例
Bean实例
容器对象存储在Map中
解析配置文件
读取Bean的配置信息
构建BeanDefinition入口
registerBeanPostProcessors(beanFactory)
标记A为正在创建中
processAliasRegistration(Element ele)DefaultBeanDefinitionDocumentReader
封装
cancelRefresh(ex);
三级缓存有
IOC容器反射+工厂
finishBeanFactoryInitialization(beanFactory)
Document
InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
发现A实例正在创建
prepareBeanFactory(beanFactory)AbstractApplicationContext
0 条评论
回复 删除
下一页