Spring 初始化时序图
2020-11-02 17:14:10 170 举报
Spring 初始化时序图描述了 Spring 容器在启动过程中,如何通过读取配置文件、实例化Bean对象、装配Bean对象和发布Bean对象等步骤来完成整个应用程序的初始化。首先,Spring 容器会读取配置文件,解析出 Bean 的定义信息;然后,根据这些定义信息,实例化 Bean 对象;接着,将 Bean 对象装配到 IoC 容器中,完成依赖注入;最后,发布 Bean 对象,使得其他组件可以获取到该 Bean 对象并使用它。整个过程是有序、自动化的,大大简化了应用程序的开发和维护工作。
作者其他创作
大纲/内容
parseBeanDefinitions()
setConfigLocations()
resolveViewName()return View()
createBeanDefinition()
handleInternal()
这里最终操作的是BeanDefinitionHolder对象,
AbstractNestablePropertyAccessor
getAopProxyFactory()
AbstractHandlerMapping
MethodBeforeAdviceInterceptor
chain.isNotEmpty()
从xml中解析出Bean定义
初始化模板处理器
读取到的配置文件进行编码,然后通过输入流的方式对文件进行解析
这里是针对spring单独启动IOC时候的入口
AbstractAutowireCapableBeanFactory
接收到请求
refreshBeanFactory()
doCreateBean()
InvocationHandler#invoke()
IOC容器初始化完毕后,开始初始化springmvc的组件
setValue()
postProcessXml(root)
getSingleton()
init()
FrameworkServlet
configureAndRefreshWebApplicationContext()
解析ModelAndView
getModelAndView()return ModelAndView()
后置增强解析
IOC启动加载时序图
这里会分别解析<import/><Alias> <beans/></bean> 四种标签定义的Bean,但是很少使用前三种,一般使用的是<bean/> 定义bean,所以,这里直接进入processBeanDefinition方法中对<bean/>标签进行解析
parseDefaultElement()
initWebApplicationContext()
如果获取不到,就从父容器进行获取
AdviceSupport
hanlder()
invokeJoinpointUsingReflection()
before
判断容器是否存在,有则销毁容器,没有则创建
获取处理器执行链
初始化视图预处理器
AopUtils
createAopProxy()
重定向时,路径携带参数的设置
开始为springioc注入bean了
registerBeanDefinition()
执行原始的方法,只是在此基础上,增强了before() 和 after()
applyPropertyValues()
XmlWebApplicationContext
注入Bean的依赖
doService()
最终的到Bean的实例
回调
processLocalProperty()
ApplicationContext
定位资源
BeanDefinitionReaderUtils
最终干实事的方法,do开头
每个代理的类,不一定都存在通知,所以这里不一定有值
获取到bean对象,返回
调用了自己类中封装的后置处理方法
AbstractRefreshableApplicationContext
loadBeanDefinitions()
mvc调用阶段
ModelAndView
在上一步得到BeanDefinitionHolder对象后,最后调用工具类对BeanDefinition进行注入到IOC中
DispatcherServlet
createProxy()
initRequestToViewNameTranslator
载入Bean定义,主要这里又使用了一个委派模式,在当前类中只定义了抽象的loadBeanDefinitions方法,具体的实现调用子类容器
AfterReturningAdviceInterceptor
调用子类实现的方法
如果对象既不能在单例池中获取,也没有正在创建,则通过对象工厂获取bean,再将创建好的对象放入到二级缓存中
DI时序图
DefaultAopProxyFactory
初始化异常拦截器
initStrategies()
对接DI部分
这里只是一种情况,可以直观的看到 ServletOutputStream.write()
processBeanDefinition()
ProxyFactory
parseBeanDefinitionElement()
DispatchServlet
registerBeanDefinitions()
创建代理对象,主要提供了两种,CGLIB和JDK动态代理,根据代理的目标进行选择代理类
AbstractBeanDefinitionReader
前置增强解析
applyBeanPostProcessorsBeforeInitialization()
单例池中获取不到,则证明该对象并不是在启动的时候被创建的,而是需要后期做依赖处理,所以从二级缓存中获取正在被创建的对象
AbstractBeanFactory
getHandlerAdapter()
如果获取到的通知为空,那么直接调用目标方法,mothod.invoke()
ProxyCreatorSupport
详细对<Bean>元素中配置的Bean定义其他属性进行解析
chain.isEmpty()
doDispatch()
初始化springmvc9大组件
renderMergedOutputModel()
postProcessAfterInitialization()
getHandler()
DefaultListableBeanFactory
JdkDynamicAopProxy
refresh()
初始化后置回调入口
配置整个spring容器,最终调用 refresh方法来启动容器
开始调度请求
doLoadBeanDefinitions()
initMultipartResolver
这里利用的是反射对属性进行注入的
BeanWrapperImpl
初始化处理器映射器
getInterceptorsAndDynamicInterceptionAdvice()
启动完毕
bean
创建Bean工厂
AbstractAutoProxtCreator
真正的属性填充,例如ABean中依赖了另一个BBean,需要将BBean依赖到ABean中,如果BBean未初始化,则需要将BBean初始化
这里会根据命名空间对xml进行解析,一般情况下都是使用的默认的,所以直接进默认的解析器中
初始化XmlBeanDefinitionReader类,读取相应配置文件,最终,根据读取的配置文件,使用AbstractBeanDefinitionReader对Beandefinition进行载入
这里使用了委托模式进行解析,所有的节点信息被定义在BeanDefinitionParserDelegate类中
AbstractRefreshableConfigApplicationContex
doGetBean()
createBeanInstance()
initThemeResolver
doLoadDocument()
DefaultSingletonBeanRegistry
调用了自己类中封装的前置处理方法
getResource()
刷新初始化容器
initLocaleResolver
onRefresh()
setPropertyValues()
chain
AbstractView
资源加载
根据执行完毕后,得到的视图名称,创建视图和模型对象
obtainFreshBeanFactory()
处理各种属性
initServletBean()
ObjectFactory singletonFactory
getBean()
ReflectiveMethodInvocation
文件上传校验
createBeanFactory()
首先,要知道启动spring的入口,spring启动的入口就在Servlet#init() 中,只要找到了这个方法,就能一步步的找到spring启动的整个过程。
processDispatchResult()
拿到root节点,解析root节点
创建代理类阶段
告诉子类刷新内部bean工厂
proceed()
render()
applyBeanPostProcessorsAfterInitialization()
根据实际情况,判断返回的代理对象是哪一种,CGLIB和JDK
当上面Spring启动完毕后,在调用ApplicationContext#getBean()的时候,会触发Spring的DI操作,解析来看看DI时序图注意: 在ApplicationContext接口中并没有直接定义getBean(),而是继承BeanFactory,BeanFactory中则定义了getBean() 找到BeanFactory的实现类AbstractBeanFactory,就能找到getBean()的实现
getParentBeanFactory()
初始化本地语言环境
Servlet
RequestMappingHandlerMethodAdaper
AbstractAutowireCapableBeanFactory
通过处理器适配器得到试图模型
这里主要对三种情况进行处理,最终拿到从资源路径中读取到Resource:1.从classpath下读取配置文件2.从URL中读取配置文件 3.既不是classpath也不是URL中读取
preProcessXml()
ClassPathXmlApplicationContext
得到AbstractBeanDefinition对象
初始化web容器
使用工具类进行创建Bean
对Bean属性填充
给定指定的模型准备视图,并将其与静态合并属性和RequestContext属性,如果有需要,会委托renderMergedOutputModel进行渲染
public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(\"classpath:application-web.xml\"); context.refresh();}
执行请求处理的方法,执行并返回
DefaultBeanDefinitionDocumentReader
wrapIfNecessary()
AbstractFeedView
new JdkDymicAopPorxy()new ObjenesisCglibAopProxy()
这里没有对其进行实现,直接返回了Bean的实例
populateBean
得到BeanDefinitionHolder对象
applyBeanPostProcessorsAfterInitialization
SpringAOP部分是在DI过程中被执行的,换个思路,如果将AOP放入到IOC部分,那么不能够完全的将Bean初始化完毕,所以只能是在DI部分进行处理AOP切面。SpringAOP是通过实现BeanPostProcessor接口,来完成对Bean的后置处理器的监听,当Bean被注入容器中,发生调用的时候,会触发监听器,执行前置后置监听,从而达到了AOP效果AOP处理是在AbstractAutowiredCapableBeanFacotry类中生成了Bean的后置处理器,那么入口就找到了,继续画时序图
XmlBeanDefinitionReader
doRegisterBeanDefinitions
初始化视图转换器
获取所有的拦截通知
AbstractApplicationContext
依然获取不到,就直接创建,并且对属性进行填充
多文件上传的组件
setPropertyValue()
如果对象在单例池中存在,则从单例池中获取并返回
invokeHandlerMethod()
AbstractPropertyAccessor
依赖注入阶段
HandlerExecutionChain
AOP时序图
initHandlerExceptionResolvers
BeanDefinitionParserDelegate
如果获取到的通知不是空的,那么直接循环调用
初始化阶段
createBean()
HttpServletBean
调用不同的视图解析器,使用response将试图写到浏览器
DefaultResourceLoader
将流和Resuorce转换成Document对象进行解析
初始化参数适配器
AbstractHandlerMethodAdaper
initializeBean()
initViewResolvers
checkMultipart()
initHandlerMappings
代码植入阶段
initFlashMapManager
initHandlerAdapters
after
收藏
0 条评论
下一页