Spring源码
2020-09-04 10:25:15 0 举报
Spring源码解析流程
作者其他创作
大纲/内容
如何将对象创建出来
此时已经创建出来DefaultListableBeanFactory对象了,但没有数据
SimpleInstantiationStrategy
BeanUtils
如何将配置文件加载到配置文件中
做一个 是否为单例&&是否为一个循环依赖&&当前单例是否在创建中的一个判断找到addSingletonFactory方法,点进去
返回
createBean方法中的[doCreateBeanBeanWrapper:包装bean,里面有bean的全部数据找到一个createBeanInstance得到一个包装bean的方法,点进去然后就是一系列健壮性判断,都不用管因为我们是无参的,直接找对应的instantiateBean,点进去
返回到createBean处
DefaultSingletonBeanRegistry
然后点createBean,找到抽象方法createBean
DefaultListableBeanFactory
声明当前这个类正在被创建,将当前对象放入一级缓存中
spring工厂的后置增强(可以修改bean工厂的信息)
执行getSingleton中的createBean得到一个sharedInstance对象,点getSingleton方法
点doRegisterBeanDefinitions(此时 把document的各种元素传过来了)再点parseBeanDefinitions( 前置增强,留一个增强的位置 preProcessXml) {因为我们只有bean,所以}执行此方法parseDefaultElement找到对应的processBeanDefinition(此时我们是bean类型)bdHolder中存放着bean标签的元数据,然后点registerBeanDefinition(开始注册我们的信息)
Spring通过当前的BeanDefinition中的信息获取到类的Class对象,通过反射获取对象实例,并且将对象实例放入到SingletonFacories(三级缓存)中 如果涉及到循环依赖,当前三级缓存中的数据,会被放到earlySingletonObjects(二级缓存)中如果没有涉及到循环依赖,当前三级缓存中的数据会被移除,初始化成功的数据,会被放到SingletonObjects(一级缓存)中
loadBeanDefinitions接口,找到其实现类
DefaultListableBeanFactory类中的preInstantiateSingletons方法中的beanNames就是我们配置文件中的所有id经过一系列判断,我们走else中的getBean(前缀“&”判断是否为工厂bean)
经过判断是否为多例,当前对象是否有父工厂,类型等一系列判断,都没进RootBeanDefinition类型的mdb,代表他有配置文件的所有元数据getDependsOn 代表创建类A之前,先创建getDependsOn里面的,因为我们没有设,所以不走这 因为我们是单例,所以走这 if (mbd.isSingleton()) 模块里面
点return的loadBeanDefinitions找try中的doLoadBeanDefinitions(inputSteram就是我xml文件的字节流)(dom4j 和 sax是java中解析xml文件的两种方式,spring中规定的是sax,在此处说明了)找到registerBeanDefinitions(把配置文件加载成了Document对象,里面有各种各样的标签 <beans> <bean>)点registerBeanDefinitions找到其对应的方法,再找其实现类
XmlBeanDefinitionReader
然后再点return处的doGetBeandoGetBean方法中的beanName可以理解成拿到bean的唯一标识,也就是id getSingleton(beanName):看看一级缓存里有没有这个对象,有的话就不用再创建了
点registerBeanDefinition会找到一个对应的抽象方法registerBeanDefinition找其实现类
AbstractXmlApplicationContext
AbstractApplicationContext
将对象返回,返回到doCreateBean处
点instantiateBean方法中的instantiate,发现是一个接口,找其实现类
点getSingleton,再点return处的getSingleton,发现此时啥都没干,直接返回
obtainFreshBeanFactory:告诉子类刷新内部工程refreshBeanFactory:找到其实现类
AbstractBeanDefinitionReader
new ClassPathXmlApplicationContext(\"classpath:a.xml\")
ClassPathXmlApplicationContext
DefaultBeanDefinitionDocumentReader
点getSingleton,只要不走异常,就执行addSingleton,将对象放入到一级缓存里
AbstractBeanFactory
refresh
AbstractRefreshableApplicationContext
先点for循环里的loadBeanDefinitions再点return处的loadBeanDefinitions经过一些判断,点else里的loadBeanDefinitions找到接口loadBeanDefinitions,找其实现类
将对象从三级缓存总移除,放在了二级缓存中,对象构建的差不多了,将他提前暴露出去了,如果其他对象要用,可以从二级缓存中拿到
如果一级缓存里没有这个beanName,就把他放在三级缓存里对象刚创建好,我们就把他放在了三级缓存里
postProcessBeanFactory(beanFactory)方法,是一个空的,啥都没做 点 invokeBeanFactoryPostProcessors(beanFactory)//(针对bean工厂的后置增强,spring为我们预留的拓展接口)
这两块内容是在一起的,上面的比执行getSingleton要早,下面的要晚一些,中间getSingleton做了两件事就返回了
Spring将配置文件的元数据加载成了BeanDefinition的对象,并储存在了一个DefaultListableBeanFactory的Spring工厂的一个Map里
点 if (earlySingletonExposure)中的getSingleton方法
AbstractAutowireCapableBeanFactory
PostProcessorRegistrationDelegate
是同一个类,就是里面存放着Map和List的那个工厂
loadBeanDefinitions方法找到String[]或者Resource[]在对应的地方点loadBeanDefinitions方法
BeanDefinitionReaderUtils
进行一个location的断言判断,返回count
其中的newInstance通过构造方法,创建好了对象,并返回
并且通过populateBean方法给属性赋值
通过元数据拿到当前类的类对象 final Class<?> clazz = bd.getBeanClass()通过clazz拿到了构造方法,调用instantiateClass时,把构造方法传了进去
进入到invokeBeanFactoryPostProcessors方法发现其参数就是BeanFactoryPostProcessor接口类型的集合而BeanFactoryPostProcessor接口中的方法就是做后置增强的
找finishBeanFactoryInitialization(beanFactory):(实例化所有非懒加载的单例,点进去)到finishBeanFactoryInitialization方法里,点preInstantiateSingletons()找到接口preInstantiateSingletons,再找对应的实现类
0 条评论
下一页