spring基于注解大致全体流程图
2024-05-08 15:06:06 1 举报
spring基于注解流程
作者其他创作
大纲/内容
如果两者都确定了,那么则直接使用该构造方法和参数进行实例化得到一个对象
标记当前对象要开始被创建
GeneircBeanDefinition通用的对象定义对象
addSingletonFactory向三级缓存中添加beanName和lambda表达式
是否通过getBEan()方法指定了构造方法参数值
N
parse()方法会递归调用processConfigurationClass()方法,处理新的配置类
处理处理@ImportResource注解
重点!!!
getSingleton(beanName);
doGetBean实际获取对象的操作
模块一
获取当前bean的Class对象
缓存该构造方法和构造方法参数值
不满足
否
BeanDefinition中指定了构造方法的参数值
继续遍历下一个候选者
是
如果mbd不为空且Synthetic不为true
没有
是否需要立即被加载
通过CommonAnnotationBeanPostProcessor解析处理@PostConstruct和@PreDestroy注解,找出beanType所有被@Resource标记的字段
扫描指定路径得到BeanDefinition集合
finishBeanFactoryInitialization(beanFactory);
判断beanfactory是否是BeanDefinitionRegistry类型
执行selectImports()方法,获取引入的类
是否存在@Component注解
如果传入了构造方法,则直接把这些构造方法作为候选者
判断是不是一个配置类
进行推断构造方法
根据&+beanName来获取具体的对象
将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
添加bean对象到当前bean的包装类中,并且进行包装类的初始化操作
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);从容器中获取所有的beanDefinitionNames集合
直接返回对象
获取所有的ConfigurationClass取出来
调用实现MergedBeanDefinitionPostProcessor的BPP调用postProcessMergedBeanDefinition()方法// 解析注解并缓存
BPP调用After方法
同一个方法
1、先处理BeanDefinitionRegistryPostProcessor2、再处理BeanFactoryPostProcessor
配置解析的流程如下
是否包含factorymethod
从一级缓存中获取对象
无论是否存在
遍历结束
循环调用BeanPostProcessor来完成After方法的调用
与invokeBeanFactoryPostProcessors(beanFactory)与模块一流程大致相同只不过针对的是BeanPostProcessor接口执行的是registerBeanPostProcessors方法只是注册BeanPostProcessor没有getBean方法
Import引入的类是否是ImportSelector子类
开始进行对象创建
processConfigBeanDefinitions(registry);
resolveBeforeInstantiation实例化前的处理,给BeanPostProcessor一个机会返回当前bean的代理对象
有
applyBeanPostProcessorsBeforeInitialization循环依赖BeanPostProcessor来完成before方法的调用
验证访问修饰符
如果是
从集合中获取每一个元素,来进行对象的创建
有没有
直接返回
getBean()时指定了构造方法参数
注册bean处理器,这里只是注册功能,真正调用的是getBean方法
ctor.newInstance(argsWithDefaultValues);
parser.parse(candidates);
onRefresh();
进行排序操作
1.定义注解bean信息读取器和类路径扫描器2.将Appconfig注册到
Y
递归处理,被Import进来的类也有可能有@Import注解processImports()方法
cglib
找到所有实现BeanFactoryPostProcessor接口的类
从多个Bean中确定出唯一的一个Bean
直接跳过
处理配置类的bean定义信息
进入方法
解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition
获取符合条件的Advisor
调用init-method来执行
调用AutowiredAnnotationBeanPostProcessorpostProcessProperties方法完成对属性bean赋值会调用所需赋值属性的getBean()方法循环依赖就是这样解决的
直接返回空对象
添加到符合条件的advisor集合
判断是否是原型作用域的对象
通过默认的构造器来生成
添加ExposeInvocationInterceptor的advisor
直接返回单例对象即可
BeanDefinition
存在
有多个构造方法可以使用
抛出异常
遍历普通的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
处理@ComponentScan注解
同时满足
找到所有的注入点
把AppConfig封装为一个processConfigurationClass方法
计算构造函数的最小参数个数
beanFactory.setConversionService设置类型转换服务
1、实现了Ordered接口的BeanFactoryPostProcessor进行排序操作遍历实现了Ordered接口的2、遍历实现了Ordered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
递归解析父类
做容器刷新前的准备工作 1、设置容器的启动时间 2、设置活跃状态为true3、设置关闭状态为false 4、获取Environment对象,并加载当前系统的属性值到Environment对象中 5、准备监听器和事件的集合对象,默认为空的集合
处理子流程
根据推断出来的构造方法进行实例化
调用的是ConfigurationClassPostProcessor
直接调用createBean
该构造方法是不是无参的构造方法
直接抛出异常
jdk
验证bd中是否包含Supplier
registerDisposaleBeanIfNessary回调,设置需要销毁的对象
创建容器对象:DefaultListableBeanFactory
针对当前BeanDefinition是否缓存了构造方法和构造方法参数值
registerBeanPostProcessors(beanFactory);
与模块一流程相同只不过针对的是BeanDefinitionRegistryPostProcessor接口执行的是postProcessBeanDefinitionRegistry方法
找到所有实现BeanDefinitionRegistryPostProcessor接口bean的beanName
判断候选者构造方法是不是只有一个,并且没有指定构造方法参数
initApplicationEventMulticaster();
方法参数类型
AbstractAutoProxyCreator
createBeanInstance反射创建对象
完成其他aware接口子类的设置工作
子类覆盖方法做额外的处理,
beanFactory.preInstantiateSingletons();实例化剩下的单例对象
InstantiationAwareBeanPostProcessor调用aware接口相关的方法,设置容器属性
refresh();
prepareMethodOverrides();处理<lookup-method/><replaced-method />
满足
每个ConfigurationClass解析完了之后,把ConfigurationClass对象添加到configurationClasses中
通过表达式在类上和方法上进行匹配
配置类解析流程
new AnnotationConfigApplicationContext(Appconfig.class)
获取bean对象的Class对象
prepareRefresh();
如果注入点是Required,那么是必须被注入的,那么就会报错
1、调用实现InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation方法2、如果直接生成的对象不为NULL直接执行完所有BPPpostProcessAfterInitialization方法直接返回不执行doCreateBean方法。
如果这两者任意一个为空,则继续继续进行下面的步骤
解析AppConfig对应的BeanDefinition
通过BeanPostProcessors来获取构造器或者通过选择最合适的构造器
initMessageSource();
对象的创建过程
判断是否有依赖的对象
BeanNameAware
处理加了@Bean注解的方法,将@Bean方法转化为BeanMethod对象,保存再集合中
instantiateBean使用默认的方式来进行实例化操作
直接返回普通对象
ApplicationContextAwareProcessor
将beanName放到alreadyCreated缓存
遍历所有内部类
代理模式
beanFactory.freezeConfiguration();冻结BeanDefinition
aop处理逻辑
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
从多个Bean确定唯一的一个Bean
是否为空
当前bean是否是单例对象,是否允许循环引用,当前对象是否正在被创建过程中
通过scope来获取具体的对象,直接创建即可
getBean()获取对象
aop
RootBeanDefinition包含了父类相关信息的对象定义
查找有@Aspect的注解的bean,如果有则对该bean进行扫描进行aop的相关处理,生成Advisor对象,放到集合中方便后续进行调用
是否实现了isInitializingBean接口
BeanClassLoaderAware
applyMergedBeanDefinitionPostProcessorsAutowired注解正是通过此方法实现注入类型的预解析
处理完方法体后
如果是实现了ImportBeanDefinitionRegistrar接口的bd
MessageSourceAware
判断导入的Class的类型
是否需要被跳过
populateBean中有可能重新调用此方法来创建不同的对象
直接执行postProcessBeanFactory方法
mbd不等于空,且包含init-method
多个Bean
对象非空且允许早期引用
beanFactory.addEmbeddedValueResolver设置内置的值处理器
直接开始创建对象
直接调用父容器的getBean来获取对象
是否有配置类
调用实现FatoryBean的getObject() 方法来创建对象
寻找注入点解析
递归处理当前类所实现的接口,接口中的方法可以有自己的默认实现,因此如果这个接口的方法加了@Bean注解,也需要被解析
invokeBeanFactoryPostProcessors(beanFactory);
如果参数个数匹配,则把所有参数值封装为一个ArgumentsHolder对象
实现了PriorityOrdered接口BeanDefinitionRegistryPostProcessor接口执行的是postProcessBeanDefinitionRegistry方法
缓存上面所推断出来的构造方法
createProxy
1、一般FatoryBean中getObject()生成的对象都是懒加载的2.如果其他对象使用依赖注入注解需要指定FatoryBean中需要生成的对象,则会通过getObject()生成对象来完成属性注入。
判断是否需要被代理
判断是否是单例对象
创建两个集合遍历所有的beanFactoryPostProcessors,将BeanDefinitionRegistryPostProcessor,其中直接执行BeanDefinitionRegistryPostProcessor接口中的postProcessBeanDefinitionRegistry方法
构造函数或工厂方法是否已经解析过
处理处理@Bean注解
判断BD是否是非抽象的且是非懒加载的且是单例的
调用各种beanFactory处理器
invokeInitMethod执行初始化方法
开始遍历候选者
为上下文初始化message源,即不同语言的消息体,国际化处理
BeanFactoryPostProcessor主要针对的操作对象是BeanFactory,而BeanDefinitionRegistryPostProcessor主要针对的操作对象是BeanDefinition
对象不为空且参数为空
如果没有传入构造方法,那么获取当前BeanDefinition对应的beanClass中的所有构造者方法作为候选者
postProcessBeanFactory(beanFactory);
调用processImports方法处理导入的类
生成对应的ImportBeanDefinitionRegistrar的实例对象
一个Bean
BPP调用before方法
递归调用processConfigurationClass()方法,处理新的配置类
判断是否直接确定了构造方法和构造方法参数值
执行BeanFactoryPostProcessors流程图
1、对实现了PriorityOrdered接口的BeanFactoryPostProcessor进行排序2、遍历实现了PriorityOrdered接口的BeanFactoryPostProcessor,执行postProcessBeanFactory方法
从二级缓存中获取对象
如果parentBeanFactory存在,并且beanName在当前BeanFactory不存在
BeanFactoryAware
创建完对象后
一级缓存中没有且当前对象正在被创建过程中
直接跳转下一个
registerListeners();
获取当前容器的父容器parentBeanFactory
进行代理的创建
放到当前configClass的importBeanDefinitionRegistrars属性中
内部类也是配置类
先创建依赖的对象
创建三个空集合将BeanFactoryPostProcessor按实现PriorityOrdered、实现Ordered接口、普通三种区分开
createBean()
会生成具体的代理对象
找到几个Bean
通过AutowiredAnnotationBeanPostProcessor解析把标注有@Autowired注解的属性转换为Metadata元数据信息
对候选者进行排序,按构造方法的参数个数降序排序,参数个数多的在前
从此方法开始进行对象的创建,包含实例化,初始化,循环依赖,AOP等核心逻辑的处理过程
从1,2,3级缓存中判断是否有具体的对象
是否是FactoryBean类型
如果Import的类型是普通类,则将其当作带有@Configuration的类一样处理调用processConfigurationClass()方法
ApplicationContextAware
匹配不上
对实现了FactoryBean接口的子类来进行调用和处理工作
构造推断方法
匹配
调用实例化策略来完成实例化操作
普通类型
遍历BeanDefinition
transformedBeanName(name)转换bean的名称
把AppConfig封装为一个ConfigurationClass
根据注入点类型找Bean
遍历每个注入点
生成完整对象进行返回操作
获取默认的构造方法来进行实例化操作
使用自动注入构造器生成
最佳候选出最佳的Bean
进行规则匹配
autowireConstructor通过此方式来生成对象,并且返回
通过factorymethod来生成具体的对象并且返回
AppConfig中是否存在内部类
处理@Import注解
初始化剩下的单实例(非懒加载的)
如果配置类上加了@PropertySource注解,那么就解析加载properties文件,并将属性添加到spring上下文中
doCreateBean实际创建对象的方法
导入spring的配置文件
获取BeanDefinition对象并且进行检查操作
addSingleton将生成的完整对象设置到一级缓存中,方便后去来进行获取
没有找到
构造器有参数
计算差异量,根据要参与构造函数的参数列表和本构造函数的参数列表进行计算
判断当前对象是否正在被销毁
判断有没有通过getBean()方法指定构造方法参数值
isPrototypeCurrentlyInCreation(beanName)当前对象是否正在被创建过程中
直接调用afterPropertiesSet方法来设置属性
把这个Bean直接进行注入
populateBean完成属性的填充工作涉及到循环依赖问题
单例对象的双重检查操作,接着从一级开始获取,没有的话,从三级获取,最终返回实际需要的对象
留给子类来初始化其他的bean
属性类型
遍历未再次处理过的ConfigurationClass
如果当前候选者需要的参数个数小于当前的构造函数参数个数则终止
遍历所有postProcessorNames没有处理的将会通过getBean获取放入到属于类型的集合中
obtainFromSupplier通过supplier创建对象并且直接返回
初始化事件监听多路广播器
注解扫描逻辑
0 条评论
下一页