Spring源码图解
2023-12-03 13:28:19 1 举报
一张图搞清楚Spring源码流程图解
作者其他创作
大纲/内容
是
addSingletonFactory向三级缓存中添加beanName和lambda表达式
初始化事件广播器
否
创建配置类解析器ConfigurationClassParser
定义bean的时候必须有property标签来完成解析工作
在prepareBeanFactory 中添加BPP
是否是FactoryBean类型
从容器中获取到所有的BDNams
没有
applyBeanPostProcessorAfterInitialization循环调用BPP来完成after方法的调用
BeanClassLoaderAware
抛异常
判断事务的超时属性
执行BeanFactoryPostProcessor的流程
apoplyMergedBeanDefinitionPostProcessors
ConfigurationClassPostProcessorAutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorEventListenerMethodProcessorAspectJAwareAdvisorAutoProxyCreator......等等
以当前的事务状态继续执行下去
具体的属性值设置
判断是否是 REQUIRED 或 REQUIRED_NEW 或NESTED
事务的创建提交与回滚过程
判断是否实现了InstantiationAwareBeanPostProcessor
processConfigurationClass方法开始进行各个注解的解析工作doProcessConfigurationClass实际的解析工作
BeanDefinition
resolveValueIfNecessary调用此方法来完成value值得解析工作
当前bean是否是单例对象是否允许循环引用是否正在被创建
执行后续的处理逻辑
什么工作都不处理,在正常的业务逻辑之后再进行调用处理
进行国际化相关的操作
不存在
determineTransactionManager获取事务管理器
isPrototypeCurrentlyInCreation当前对象是否正在被创建过程中
7、initMessageSource
标记当前对象要开始被创建
从容器中获取所有的BeanDefinitionNames集合 beanNames = new ArrayList<>(this.beanDefinitionNames)
是否实现了InitializingBean接口
有
对象为空且允许早期引用
getTransaction获取事务
createBean()
3、开始进入容器额创建和刷新环节 refresh()
创建CglibMethodInvocation对象
getBean()获取对象
对象中包含了保存点,连接持有器等相关信息
5、invokeBeanFactoryPostProcessor 执行BFPP接口中的方法
获取当前bean的Class对象
无
3、prepareBeanFactory 给容器对象完成属性的赋值操作
将普通的BPP完成注册功能
12、finishRefresh() 完成刷新
进行封装到一个委托对象中
会有很多种不同的类型来进行相关的解析操作
判断BD 是否是非抽象 且 非懒加载 且 是单例
是,添加到list
判断当前事务传播特性是否是 MANDATORY
AOP
postProcessBeanFactory()
从此方法开始进行对象的创建,包含了实例化,初始化,循环依赖,AOP等合兴逻辑的过程,此步骤是最最核心的点
parseDefaultElement()使用默认方式进行解析
通过factorymethod来生成具体的对象并返回
动态代理
在业务流程之前先执行around的前置逻辑invokeAdviceMethod()
开始填充
extend
会生成具体对象的代理对象
obtainFromSupplier通过supplier创建对象并直接返回
通过scope来获取具体的对象,直接创建即可,一般不会进这条路径
分别获取name 和value 对象
向容器中添加BeanPostProcessorImportAwareBeanPostProcessor.class
获取PropertyValue的自动注入模式
判断事务的传播特性是否是not supportted
1、setConversionService()设置类型转换服务
获取5号位置的Before元素
拦截器链中包含多少个对象由之前定义的消息通知来决定,如果全部定义的话包括6个
autowireByType()完成注入
BeanDefinitionReader
如果一个事务方法嗲用了另一个事务方法,需要进行传播特性的判断,因为传播特性会影响事务的提交和回滚
上述主要是BDRPP接口方法的执行下面是BFPP接口方法的执行
如果mbd不为空且Synthetic不为true
只是在alreadyCreated集合中添加对象即可
满足
设置自动提交关闭
判断当前对象是否正在被销毁
1、调用父类构造方法 创建PathMathingResourcePatternResolver,解析配置文件
注册监听器为了方便接受广播的时间
调用此方法 afterSingletonsInstantiated来完成bean的处理工作
获取容器中所有实现了BeanPostProcessor接口的子类的名称
根据指定的路径来进行扫描操作 Set<BD> list = findCandidateComponents(basePackage)
mbd不为空且包含init-method
直接调用父容器的getBean来获取对象
将容器中包含的BPP按照不同的分类放到不同的集合中去
开始事务startTransaction
直接返回单例对象即可
applyPropertyValues
调用构造方法
是否需要立即被加载
直接忽略
开始调用具体的方法
调用init-method 来执行
getTransactionAttribute获取某一个方法对应的具体的事务属性等相关信息
执行具体业务逻辑的时候是否有异常情况
将实现PriorityOrdered接口的BPP进行排序并完成注册功能
获取3号位置的After素
实现了PriorityOrdered接口的BPPList<BPP> priorityOrderedPostProcessors
将解析完成的BeanDefinition对象注册到容器中的BDMap和BDNames中
3、处理用户传进来的自定义BFPP
PropertySourcePlaceHolderConfigurer
获取bean对象的Class对象
applicationContext
AspectJMethodBeforeAdvice
完成Spring自带或者用户自定义的BeanPostProcessor的解析
completeTransactionAfterThrowing完成当前事务的回滚
创建当期bean的包装对象,默认为空
不满足
获取默认的构造方法来进行实例化操作
通过默认的构造器来生成
pvs != null
完成整个容器的启动,所有的对象都准备完成,可以进行后续的业务流程操作。清除上下文缓存、初始化生命周期处理器,发送刷新完成事件
是否为空
开始执行Around消息通知的执行逻辑
cleanupTransactionInfo清除事务信息
根据&+beanName去获取对象
经过一系列invoke方法的执行,调用到业务方法中,然后开始返回
解析@Bean
获取数据库连接
2 将currentRegistryProcessors集合中的值合并到registryProcessors中
优先处理实现了PriorityOrdered接口的BFPP对象,然后是Ordered接口的对象,最后是两者都没有实现的对象主要是调用FBPP中的postProcessBeanFactory()
直接返回
是否是默认的标签bean
AspectJAfterthrowingAdvice
同时满足
先获取0号位置的元素exposedInvocationInterceptor
DataSourceTransactionObject创建数据源事务对象
一级没有且对象正在被创建过程中
父容器不为空且BDMap不存在当前bean
对象不为空且参数为空
spring.handlers
可以自由扩展,修改BeanFactory中的相关信息,但是使用最多的是对BeanDefinition的修改操作
isExistingTransaction判断是否已经存在一个事务
doGetBean实际获取对象的操作
commitTransactionAfterReturning以正常的方式提交事务
开始postProcessBeanDefinitionRegistry()
设置事务属性
解析@PropertySource
XmlBeanDefinitionReader
registerDisposableBeanIfNecessary类似回调,设置需要销毁的对象
autowireByName()完成注入
对PropertyValues进行一系列的验证工作
prepareTransactionInfo创建事务信息对象,包含了事务处理过程中的相关属性值
1、创建一个空的集合,用来存储已经执行过的BFPPSet<String> processedBeans = new HashSet<>()
在实际业务逻辑处理之前,先把核心的before中的逻辑执行了,开始调用MethodBeforeAdvice中的before方法
从一二三级缓存中判断是否有具体对象
调用postProcessorProperties方法进行属性的设置工作
判断是否是单例对象
TransactionInterceptor.class类中invokeWithinTransaction方法中开始事务的处理
识别到spring中包含的对象和自定义的对象
invokeJoinpoint
getSingleton()
AutowiredAnnotationBeanPostProcessor@Autowired,@Value
setPropertyValues给bean对象设置属性值
判断mbd的Synthetic是否为true,同时包含InstantiationAwareBeanpostProcessor
有还是没有
9、onRefresh()
判断是否是原型作用域的对象
事务处理流程
doBegin开启事务
2、loadBeanDefinitions() 加载配置文件完成BD的价值和解析工作
当所有的bean对象都创建完毕之后
获取4号位置的Around元素
getTransactionAttributeSource获取事务方法所对应配置的事务属性集合
核心方法processConfigBeanDefinitions(registry)处理配置类的解析信息
返回实际的对象
在填充属性的过程中涉及到循环依赖的问题
从 -1 的下标位置开始依次获取对应的元素
TransactionSynchronizationManager.getResource通过此对象来获取连接持有器,在第一次调用的时候,对象一定为空,后续创建完成之后会进行设置工作,方便下一次获取
invokeInitMethod执行初始化方法
调用invokeAdviceMethodWithGivenArgs()
判断是否实现了PriorityOrdered接口
ApplicationContextAwareProcessor完成其他aware接口子类的设置工作
获取BD对象并进行检查操作
handler.parse() 通过不同的handler对象去解析不同的标签元素
CommonAnnotationBeanPostProcessorInitDestroyAnnotationBeanPostProcessor@PostConstruct,@PreDestroy,@Resource
parseBeanDefinitions解析BeanDefinition遍历外层标签中的子标签,然后开始判断使用什么样的方式进行解析操作
beanWrapper是否为空
解析父类
最终会嗲用到实际的befor消息通知
此图中虽然配置了具体的advice的顺序,但是根据实际的配置情况,顺序可能有所不同,要根据实际的业务代码来判断具体先执行哪个
添加BeanPostProcessorChecker
经常用到的BPPApplicationContextAwareProcessorAbstractAutoProxyCreatorAutowiredAnnotationBeanPostProcessorAutoWiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessorApplicationListenerDetectorAspectJAwareAdvisorAutoProxyCreatorInitDestoryAnnotationBeanPostProcessor L 主要处理了 @postConstruct 和 @PreDestroy
创建一个空的去重集合来存放扫描到的类Set<BDHolder> bds = new LinkedHashSet<>()
什么工作都不处理,直接在正常的业务逻辑执行完之后再进行调用处理
6、获取当前容器中所有实现了BDRPP接口的独享,并且判断是否实现了Ordered接口
doScan(String... basePackages)
是否包含FactoryMethod
11、finishBeanFactoryInitialization(beanFactory) 完成所有非懒加载的单例对象的实例化操作
7、获取当前容器中所有实现了BDRPP接口的对象,如果没有实现PriorityOrdered 和 Ordered
将所有spring内部的BPP进行排序并完成注册
创建新事物的状态对象
4、preInstantiateSingletons()开始独享的实例化
2、obtainFreshBeanFactory 创建容器,并且完成配置文件的加载
判断是否是NESTED
挂起当前事务开启一个新事务
BeanNameAware
判断是否是required_new
AspectJAroundAdvice
执行前置逻辑
根据当前标签的命名空间字符串去查找对应的handler处理类
parser.parse()核心的解析流程方法
解析@ComponentScan
13、resetCommonCache() 情况运行过程中产生的缓存
4、postProcessBeanFactory 默认没有实现,留给子类实现操作
添加到一级缓存并清空二三级缓存
在spring中默认没有任何实现,模板方法但是在springboot中启动了web容器
进行实例化后的属性值的设置工作
3 执行BDRPP接口中的方法 invokeBeanDefinitionRegistryPostProcessors
判断事务的传播特性是否是Never
解析该注解包含的属性值
ExposedInvocationInterceptor
只是记录了一堆日志信息
pjp.proceed(args)pjp对象包含了从glibMethodInvocation对象,所以在进行嗲用的时候能够回到拦截器链中继续向下执行
6、注册BeanPostProcessorregisterBeanPostProcessor(beanFactory)
@Bean的单例问题
获取当前容器的父容器
2、判断当前beanFactory是否是BeanDefinitionRegistry
从集合中获取每一个元素,来进行对象的创建根据beanName来获取完整的BD对象,而且是RootBeanDefinition
调用实例化策略来完成实例化操作
判断是否有异常
创建两个空的集合对象来进行去重操作分别存放配置类和已经解析过的配置
事务创建提交与回滚流程
addSingleton,将生成的完整对象设置到一级缓存中,方便后面获取操作
实现了Ordered接口的BPPList<BPP> orderedPostProcessorNames
解析@ImportSource
看到的是反编译之后的字节码文件调用任何方法执行的都是DynamicAdvisedInterceptor对象
先从一级缓存中获取对象
AspectJAfterAdvice
直接跳过
true
如果包含AOP的相关处理,那么会在此处生成Advisor对象,方便后续进行调用
BeanFactoryAware
ConfigurationClassPostProcessor
// 在spring中一般对象都是单例的,// 目的是为了每次获取Person对象的时候都是同一个@Configurationpublic class MyConfiguration{ @Bean public Person getPerson(){ return new Person(); }}
AOP的调用流程
ConfigurationClassPostProcessor 添加BPP
获取当前bean的构造方法来生成具体的对象
createTransactionIfNecessary创建事务
遍历所有的beanName,根据beanName获取bean对象
返回空对象
开始进行对象的创建
把bean对象返回回去
通过BPP来获取构造器或通过选择最合适的构造器
存放普通的PPList<BPP> nonOrderedPostProcessorNames
从集合中循环判断每一个对象并注册到当前容器中
获取2号位置的AfterReturning元素
获取代理对象,并且执行对应的方法进行处理
本质是添加到销毁的集合中
创建一个空的list集合,用来存放BD
3、freezeConfigurations()冻结BeanDefinition
调用ObjectFactory的getObject() 方法来创建对象
4、创建存放BDRPP的集合对象,用来存储当前正在执行过程中的BDRPPList<BeanDefinitionRegistryPostProcessor> currentRegistryProcessor = new ArrayList<>()
不同的标签有不同的处理类,具体的处理逻辑可能不同,但最终都会获取到完成的beanDefinition对象此处会判断是否要完成某些内部bean的BD的加载会有一堆内部对象的价值,大部分和注解相关
BeanFactoryPostProcessor接口
存放Spring内部的BPPList<BPP> internalPostProcessors
intercept()开始执行具体流程
AOP 的调用流程
4 清空当前的 currentRegistryProcessors
1 将currentRegistryProcessors进行排序操作
resolveBeforeInstantiation给BPP一个机会返回当前bean的代理对象
有一个单例对象的双重检查操作,接着从一级开始获取,没有的话就从二级获取,再没有的话从三级获取,最终返回实际需要的对象
8、执行所有registryProcessors和regularProcessors中的postProcessBeanFactory接口的方法
createBeanInstance
ApplicationContextAwareProcessor
ImportAwareBeanPostProcessor
设置保存点以当前事务状态继续运行
存在
不是
定义不同的集合来区分不同的BPP
populateBean完成属性填充工作
后面会调用一系列的invoke方法
直接调用createBean
抛出异常
使用自动注入的构造器来生成
invocation.proceedWithInvocation()执行方法的具体处理逻辑
生成的完整对象进行返回操作
isValidateExistingTransaction验证当前存在的事务
ApplicationListenerDetector
执行后置的处理逻辑
创建Spring应用程序上下文
创建空事务
2、设置配置文件路径到当前应用程序中
当前BD中是否包含propertyValue对象
getInterceptorsAndDynamicInterceptionAdvice获取整个消息通知的责任链,按照链式结构依次调用执行
经过一系列的loadeBeanDefinitions方法,最终为了完成当前配置文件的加载工作内部调用doLoadBeanDefinitions方法,完成配置文件的解析工作
执行around的后置逻辑
添加bean对象到当前bean的包装类中,并进行包装类的初始化操作
instantiateBean使用默认的方式来进行实例化操作
验证访问修饰符
通过一些列的 add set ignore register开头的方法,设置属性值
验证BD中是否包含Supplier
先创建依赖对象
遍历结合中所有存在的PropertyValue
8、initApplicationEventMulticaster()
从二级缓存中获取对象
invokeAwareMethods调用aware接口相关的方法,设置容器属性
调用incodeAdviceMethod()
什么工作都不处理,直接向下执行,获取下一个元素,因为afterThrowing对应的是程序过程中出现的异常情况,此时还没有执行任何代码,所以直接跳过
autowireConstructor通过此方式来生成对象并返回
挂起空事务
调用JDK或者CGLIB生成
prepareMethodOverrides处理lookup-method,replace-method
RootBeanDefinition包含了父类相关信息的对象定义对象
10、registerListeners()
调用afterPropertiesSet方法来设置属性
doCreateBean
parseCustomElement使用额外的方式进行解析
ctor.newInstance()
把当前对象设置到ThreadLocal变量中,方便在链中直接进行获取,并且根据原来的下标依次获取元素
获取1号位置的AfterThrowing元素
判断是否有依赖的对象
implement
AOP的调用过程在创建代理对象的过程中,是通过wrapIfNecessary方法来创建对象的
判断txAttr不为空且txAttr包含具体的方法名称
1.设置容器的启动时间2.设置活跃状态为true3.设置关闭状态为false4.获取Environment对象,并加载当前系统的属性值到Environment对象中5.准备监听器和事件的集合对象,默认为空的集合
挂起当前事务以非事务状态开始运行
txAttr不为空且事务管理器不为空
直接开始创建对象即可
1、prepareRefresh() 前戏,做容器刷新的准备工作
递归处理成员嵌套类
BeanDefinitionRegistryPostProcessor
doLoadDocument()将配置文件解析成文档对象,方便通过父子节点的方式获取出对应的标签元素registerBeanDefinitions() 解析元素doRegisterBeanDefinitions 注册到容器
2、addEmbeddedValueResolver()设置内置的值处理器
执行异常处理
对实现了FactoryBean接口的子类进行调用和处理工作
返回对象
GenericBeanDefinition通用的对象定义信息
initializeBean完成当前bean的初始化
直接返回对象
doGetTransaction
判断bean是否实现了SmartInitializingSingleton接口
1、createBeanFactory()-->DefaultListableBeanFactory 创建容器独享
AspectJAfterReturningAdvice
获取事务定义信息
模式判断
5、获取当前容器中所有实现BDRPP接口的对象
new ClassPathXmlApplicationContext(\"applicationContext.xml\")
将实现Ordered接口的BPP进行排序并完成注册功能
用的比较多的扩展的两个子类
applyBeanPostProcessorsBeforeInitialization循环调用BPP来完成before方法的调用
返回
判断当前对象是否是先添加的对象
解析过滤后的BD,然后进行解析操作
enhanceConfigurationClasses(beanFactory)对当前配置类进行增强操作
是否是否和规则的配置类
0 条评论
下一页