spring ioc源码分析
2024-05-08 13:20:42 1 举报
spring 源码分析IOC加载流程
作者其他创作
大纲/内容
调用MyBeanFactoryPostProcessorConfigurationClassPostProcessor
会在这解析
@Import - ImportBy
processPropertySource(propertySource)解析属性资源文件@PropertySource
bean没有实现任何优先级接口
currentRegistryProcessors.add(getBean())创建Bean然后存入到集合中
ClassPathScanningCandidateComponentProvider
findCandidateComponents
basePackages
for
③
递归处理直到处理为 else configClass
BeanPostProcessor
JDK
再次当作配置类解析,如果不是配置类最终会当作普通Bean定义注册
this.deferredImportSelectorHandler.process()
注解方式
解析@Bean
修改
getBean()判断是不是FactoryBean &Car getObject()先从一级缓存中拿 如果拿到直接返回,没有拿到调用createBean
selector instanceof DeferredImportSelector是否实现接口
BeanDefinitionReader读取配置xml、注解
BeanFactoryPostProcessor
postProcessBeanFactory给ConfigurationClassPostProcessor创建动态代理
PostProcessorRegistrationDelegate
invokeBeanFactoryPostProcessors
BeanDefinition(顶层核心接口,封装了生产bean的一切原料,含底层bean如:ConfigurationClassPostProcessor)
isCandidateComponent
BeanFactory(顶层核心接口,简单工厂模式)负责生产bean
@Import - ImportBeanDefinitionRegistrar
在这里典型的BeanDefinitionRegistryPostProcessor就是ConfigurationClassPostProcessor用于进行bean定义的加载 比如我们的包扫描,@import 等
会在解析完配置后调用processDeferredImportSelectors()解析
2
类@注解
BeanDefinitionScanner手动指定扫描包
加载已注册的Bean定义的后置处理器也就是之前注册的:this.reader = new AnnotatedBeanDefinitionReader(this) 和之前注册的配置类,从里面可以找到实现了BeanDefinitionRegistryPostProcessor接口的,也就是ConfigurationClassPostProcessor
在这里把之前@Import导入的普通类注册为Bean定义
抽象
将配置得class注册Bean定义:ConfigurationClassPostProcessor
ConfigurationClass
addImportBeanDefinitionRegistrarthis.importBeanDefinitionRegistrars.put
初始化initializeBeaninitMethod destory
这里是把importBeanDefinitionRegistrars实例缓存起来
符合
this.deferredImportSelectors.add
设计师BeanDefinitionRegistry
循环找出遗漏未解析的配置类
BeanPostProcessor扩展点:用于处理bean生命周期
postProcessors就一个ConfigurationClassPostProcessor
ClassPathXmlApplicationContext
加载BeanDefinition②
ConfigurationClass#addBeanMethod()Set<BeanMethod>
@Import - importedBy
refresh()
将@ComponentScan的信息存到scanner中包含includeFilters、excludeFilters、lazyInit、basePackages、basePackageClasses
BeanDefinitionRegistry注册bean
循环从所有BeanDefinition拿到配置类并且标记:CONFIGURATION_CLASS_ATTRIBUTE属性:分两种:1.full完整配置类 @Configuration2.lite精简版配置类 @Component@ComponentScan @ImportResource @Bean
注册
调用自定义类MyBeanFactoryPostProcessor
自动装配待定
此处只把所有@Bean方法读取出来add到Set中,并未解析成BeanDefinition
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath)
getBean
Aop
bean 实现接口
ClassPathBeanDefinitionScanner
doScan
类xml
this()
橱柜店 - 注解ApplicationContextAnnotationConfigApplicationContext
ImportBeanDefinitionRegistrar
判断是否符合候选组件要求
bean
!candidates.isEmpty()
do
BeanDefinitionRegistryPostProcessor注册bean定义
解析@ImportResource
scanner = new ClassPathBeanDefinitionScanner
接待扫描BeanDefinitionScanner @Component
@Bean和@Import的BeanDefinition在此处注册
图纸BeanDefinition
mybatis
子接口
实现了延时ImportSelector
实例化createBeanInstance反射实现
到此为止所有实现了BeanDefinitionRegistryPostProcessor接口都调用完毕,最主要的工作还是调用了内置的ConfigurationClassPostProcessor扫描Bean定义,和调用自定义BeanDefinitionRegistryPostProcessor注册Bean定义
④
postProcessBeanDefinitionRegistry(registry)processConfigBeanDefinitions(registry)
衣柜@Bean
configClass普通组件当作配置类
IOC容器
invokeBeanDefinitionRegistryPostProcessors
@Import - ImportBeanDefinitionRegistrar
集成mybatis需要重写
在这里注册
从容器中获取实现了BeanDefinitionRegistryPostProcessor接口的bean
1
this.reader.register(componentClasses)注册配置类
②
selector.selectImports()调用方法返回字符串数组asSourceClasses反射为Class循环处理
candidates候选的BeanDefinition
for
ImportSelector
填充属性populateBean@Autowired @Value
CGLIB
excludeFilters
注册bean定义
ConfigurationClassParser
processImports
扩展点(处理bean定义,在getBean之前干预)invokeBeanFactoryPostProcessors
processConfigurationClass
你@Componentclass
解析@Import
销售BeanDefinitionReader楼盘配置类.xml
configClass.isImported()从@Import导入的
configClass.getBeanMethods()
bean实现了Ordered接口
ConfigurationClassPostProcessor
postProcessBeanDefinitionRegistry
BeanFactoryPostProcessorgetBean前可修改bean定义
工厂BeanFactory
bean实现了PriorityOrdered接口
用来扫描我们classpath下的标注了@Service @Compent @Respository@Controller
创建配置类解析器解析:@Import @ComponentScan @ImportResource @Bean
includeFilters
在这个类中,会解析加了@Configuration的配置类,还会解析@ComponentScans注解扫描的包,以及解析@Import等注解
解析@ComponentScan
在这里把之前添加的BeanMethod开始注册为Bean定义
找到候选BeanDefinitionfindCandidateComponents
结果一系列的解析(scope、lazyInit、DependsOn等)
BeanDefinitionScanner自动扫描配置类扫描包
ComponentScanAnnotationParser
parse
getImports(sourceClass)获取当前配置类的@Import注解的导入类
BeanDefinitionMap
finishBeanFactoryInitialization
@ImportResources不重要不说了
AnnotatedBeanDefinitionReaderConfigurationClassPostProcessor注册底层核心bean
接口
@Bean - beanMethods
得到当前配置类下所有@Bean方法beanMethods = retrieveBeanMethodMetadata(sourceClass)
循坏依赖(三级缓存)
是①
getBeanFactoryPostProcessors()返回为null,该beanFactoryPostProcessors需要我们手动设置
resources
Lazyscope....
asConfigClass(configClass)new一个ConfigClass使用importedBy标记是从哪个配置类中@Import进来的
ConfigurationClassBeanDefinitionReader#loadBeanDefinitions
AnnotationConfigApplicationContext
importCandidates
获取包下面所有的.class文件
100个里面只有10个满足条件
new ConfigurationClassParser
AbstractApplicationContext
衣柜店 - XMLApplicationContextClassPathXmlApplicationContext
①解析配置类
BeanDefinitionRegistryPostProcessor
第一处:BeanPostProcessorInstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
importBeanDefinitionRegistrars
forEach
this.reader.loadBeanDefinitions(configClasses)
candidateNames
没实现普通ImportSeletor
此处小细节:会调用ConfigurationClassPostProcessor的postProcessBeanFactory方法将配置类创建CGLIB代理只有full版配置类才会创建cglib代理,虽然我们在指定配置的时候不标注@Configuration也行,所以加不加注解的区别就在这里 那么加了@Configuration和不加在本质上有什么区别?当在配置类中一个@Bean使用方法的方式引用另一个Bean如果不加注解就会重复加载Bean 如果加了@Configuration则会在这里创建cglib代理,当调用@Bean方法时会先检查容器中是否存在
BeanDefinitionMainConfig.java 配置类
生命周期回调Aware@PostConstructInitializingBeaninitMethod
0 条评论
下一页