Spring源码解析(带详细注解)
2021-03-15 14:05:00 1 举报
AI智能生成
Spring源码解析,带详细注解,深度剖析AOP和IOC,一图在手搞定Spring源码
作者其他创作
大纲/内容
ioc怎么理解?
1、相当于是bean的管控交给spring
2、bean 的管控离不开依赖
3、依赖就有循环依赖的问题?
三级缓存
为什么要三级缓存?
4、第三方框架如何快速集成
举例子
mybatis
5、spring导入bean有多少种方式
xml中
@component+@componentSacan
@Bean+@Configuration
@importRegistror
@ImportSelector
什么叫做bean定义
bean定义可不可以修改
beanfactorypostprocessor
什么场景下修改?
xxxPostProcessor
BeanFactoryPostProcessor<br>
BeanDefinitionRegistryPostProcessor
BeanPostProcessor
初始化上下文
初始化无参构造方法
1、先初始化父类GenericApplicationContext——无参构造方法<br>主要是初始化了一个:<br>this.beanFactory = new DefaultListableBeanFactory()<br>
2、初始化了一个reader:<br>this.reader = new AnnotatedBeanDefinitionReader(this);<br>
注册了6个bean定义:<br>——DefaultListableBeanFactory中的map成员变量里设置kv<br>bean定义和beanName<br>
this.beanDefinitionMap.put(beanName, beanDefinition);<br> this.beanDefinitionNames.add(beanName);<br> this.manualSingletonNames.remove(beanName);<br>
ConfigurationClassPostProcessor.class
AutowiredAnnotationBeanPostProcessor.class
CommonAnnotationBeanPostProcessor.class
PersistenceAnnotationBeanPostProcessor
EventListenerMethodProcessor.class
DefaultEventListenerFactory.class
3、初始化了一个scanner:<br>this.scanner = new ClassPathBeanDefinitionScanner(this);<br>
注册3个默认过滤器<br>——放在了scanner的成员变量List<TypeFilter> includeFilters<br>
AnnotationTypeFilter(Component.class)
javax.annotation.ManagedBean
javax.inject.Named
使用初始化好的reader注册参数中的带有注解的类<br>
准备bean定义
构造一个专门用于注解的bean定义:<br>AnnotatedGenericBeanDefinition<br>
解析类上的注解信息作为成员属性metadata
解析Scope注解,并设置到AnnotatedGenericBeanDefinition
初始化一个ScopeMetadata,默认是Singleton,<br>可以从注解中解析Scope的注解
解析公共注解
Lazy
Primary<br>
dependsOn<br>
Role<br>
Description<br>
准备beanName
优先解析Component注解上的别名
其次就是类名称作为beanName
注册bean定义
this.beanDefinitionMap.put(beanName, beanDefinition);<br> this.beanDefinitionNames.add(beanName);<br> this.manualSingletonNames.remove(beanName);<br>
注册aliases
refresh
执行BeanFactory类型的后置处理:<br> invokeBeanFactoryPostProcessors(beanFactory)<br>
获取beanFactory后置处理类集合:<br> getBeanFactoryPostProcessors()<br>
获取bean定义注册的后置处理器的实例
获取bean定义注册的后置处理器的beanName:<br> BeanDefinitionRegistryPostProcessor==》ConfigurationClassPostProcessor<br>
判断当前bean定义注册后置处理器是否PriorityOrdered类型
getBean,这个bean定义注册后置处理器<br>
beanName放到Set中<br>
bean实例放到List中
执行bean定义注册后置处理:<br><font color="#f15a23">ConfigurationClassPostProcessor<br>.postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)</font><br>
准备要对注解进行解析的类的bean定义<br>——说白了就是有加的注解的类都在这个范围内
遍历注册器中的bean定义
过滤校验bean定义
Configuration注解——true
当前类是接口——false
Component/ComponentScan/Import/ImportResource注解——true<br>
检查方法上有无Bean注解——true
符合校验的放到List中——configCandidates<br>
基于Order注解进行集合configCandidates排序
将注解信息和beanName封装到configClass<br>
核心处理注解类:<br>doProcessConfigurationClass<br>
processMemberClasses
递归处理有Component注解的内部类
processPropertySource
解析@PropertySource注解的配置文件路径
追加到配置信息中<br>
处理ComponentScans
实例化ClassPathBeanDefinitionScanner 类,然后设置一些属性<br>
扫描核心方法:doScan<br>针对package指定的路径集合进行扫描
findCandidateComponents;查找合适的bean定义
核心就是isCandidateComponent方法
针对includeFilter和excluderFilter进行过滤
注册bean定义:<br>——registerBeanDefinition指定路径下的类<br>
this.beanDefinitionMap.put(beanName, beanDefinition);<br> this.beanDefinitionNames.add(beanName);<br> this.manualSingletonNames.remove(beanName);<br>
processImports
解析@Import指定的类集合
遍历集合进行处理
如果类实现了ImportSelector接口<br>
实例化ImportSelector类型实例
调用实例接口的方法selectImports,返回类集合
递归processImports处理<br>
<b>【<font color="#f15a23">扩展点</font>】如果类实现了ImportBeanDefinitionRegistrar接口</b>
实例化ImportBeanDefinitionRegistrar类型实例
把实例放到父类ConfigClass的importBeanDefinitionRegistrars集合中<br>
如果import的类不是上面的两个类型那么就按照普通配置类处理<br>——@Configuration
处理@ImportResource<br>
把location指定的配置文件集进行遍历
配置文件路径放到父类ConfigClass的importedResources集合中<br>
处理@Bean
遍历注解有@Bean的方法
将方法元信息和所属类名称封装成BeanMethod<br>
将BeanMethod设置到父类ConfigClass的beanMethods集合中
处理接口中注解有@Bean 的default方法
注意,java8+的特性
处理父类
构造ConfigClassBean定义读取器<br>ConfigurationClassBeanDefinitionReader<br>
注册@bean的bean定义以及针对import的后置处理
加载bean定义<br>
loadBeanDefinitionsForBeanMethod
loadBeanDefinitionsFromImportedResources
loadBeanDefinitionRegistrar
调用子类的registerBeanDefinitions的方法
registerBeanPostProcessors(beanFactory);
getBean获取bean
准备beanName<br>
从缓存中取bean
从一级缓存中取
singletonObjects
取不到就去找二级
从二级缓存中取
earlySingletonObjects
取不到就从找三级
从三级缓存中取
singletonFactories<br>
三级缓存是一个factory,执行getObject方法<br>并把获取到的数据缓存到二级缓存中,<br>然后删除三级缓存中的factory<br>
<b><font color="#f15a23">循环依赖的场景下,实例A的半成品就可以从factory缓存中取到<br>两个动作:<br>1、放到二级缓存中<br>2、在三级缓存中即facotory中删除</font></b><br>
如果缓存中能取到,就返回
如果获取到的bean是个工厂bean,那么就从工程bean中getObject,并返回
如果缓存中取不到,进入创建bean的流程
判断是否有父工厂类,并获取、返回
获取依赖列表,遍历并getBean
针对@DepensOn<br>
针对不同模式进行获取bean
单例模式获取bean
一级缓存查找
查到返回,查不到进行factory.getObject,<br>这里回调机制,调用参数方法的createBean
调用扩展点获取bean<br>
实现InstantiationAwareBeanPostProcessor接口
doCreateBean(核心)<br>
通过反射机制调用构造方法进行实例化<br>
通过构造方法进行实例化(复杂)
判断是否设置缓存(早期单例池)<br>
单例/允许循环依赖/正在实例化<br>
<b><font color="#f15a23">设置三级缓存-factory</font></b>
设置依赖属性<br>==》populateBean
根据Autowire的模式进行注入依赖
<b><font color="#f15a23">会把依赖的A类的Bean半成品对象从factory三级缓存中获取到并返回出去</font></b>
继续加工初始化半成品Bean<br>==》initializeBean
调用*Aware的方法<br>
BeanNameAware<br>
BeanClassLoaderAware
BeanFactoryAware
调用postProcessBeforeInitialization
调用invokeInitMethods方法<br>实现:InitializingBean接口
afterPropertiesSet
<b><font color="#f15a23">把B类从三级缓存取出,【注意】:这里不会删除三级,也不会存到二级</font></b><br>
<br>
<b><font color="#f15a23">B类的实例直接放到一级缓存</font></b><br>
<b><font color="#f15a23">设置一级缓存</font></b>addSingleton加入一级缓存
原型模式获取bean
调用参数方法的createBean
原型模式下没有做缓存,所以不能进行循环依赖
isPrototypeCurrentlyInCreation,如果是循环依赖,那么在这里会捕获到并抛出异常
扩展模式获取bean
@EnableAspectJAutoProxy开启AOP
注解基本用法<br>
5种通知方法
前置通知(@Before)<br><br>后置通知(@After)<br><br>返回通知 (@AfterReturning)<br><br>异常通知 (@AfterThrowing)<br><br>环绕通知 (@Around)
公共切入点
@PointCut<br>
JoinPoint
作为函数的参数传入切面方法,可以得到目标方法的相关信息
@Aspect
指定切面类
@EnableAspectJAutoProxy <br>
开启基于注解的AOP模式
@EnableTransactionManagement开启事务
0 条评论
下一页