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