Spring源码流程
2023-03-28 16:14:05 0 举报
AI智能生成
Spring源码流程
作者其他创作
大纲/内容
调用无参构造器<br>
this.reader = new AnnotatedBeanDefinitionReader(this);<br>主要是注册了一些跟注解相关的后置处理器为bd<br>
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);<br>跟@Condition相关
<font color="#e74f4c"><b>注册几个注解相关的后置处理器(还处于bd)</b></font>
为容器设置AnnotationAwareOrderComparator,用来解析@Order和@Priority
为容器设置ContextAnnotationAutowireCandidateResolver,<br>用来处理@Autowired依赖注入的,判断bean是否匹配的,是否可以注入的,<br>在后面解析依赖注入时会用到<br>
注册ConfigurationClassPostProcessor,解析加了@Configuration的配置类,<br>还会解析@ComponentScan、@ComponentScans注解扫描的包,以及解析@Import等注解,<br>是最为重要的BeanFactory后置处理器之一<br>
注册AutowiredAnnotationBeanPostProcessor,顾名思义就是用来处理@Autowired和@Value注解的
注册CommonAnnotationBeanPostProcessor,用来处理公共注解,比如@PostConstruct和@PreDestroy还有@Resource等
注册PersistenceAnnotationBeanPostProcessor,用来处理jpa的
注册EventListenerMethodProcessor,用来处理@EventListener注解
注册DefaultEventListenerFactory
this.scanner = new ClassPathBeanDefinitionScanner(this);<br>创建扫描器,添加默认的扫描类过滤器,加了特定的注解会被扫描到:<br>@Component、@Repository、@Service、@Controller、@ManagedBean、@Named<br>
将传进来的类注册为bd
刷新容器refresh()
prepareRefresh();<br>准备工作,比如记录容器启动时间等<br>
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();<br>获取并初始化bean工厂,即之前已经创建过的bean工厂<br>
prepareBeanFactory(beanFactory);<br>配置工厂的标准上下文特征,例如上下文的类加载器和后处理器,比如:<br>设置 BeanFactory 的类加载器,添加几个 BeanPostProcessor,手动注册几个特殊的 bean等<br>
设置类加载器
添加一个bean表达式解析器
添加属性编辑器
添加一个bean后置处理器:ApplicationContextAwareProcessor。<br>这个Processor的作用在于为实现下面几个*Aware接口的bean调用该Aware接口定义的方法,并传入对应的参数。<br>比如实现EnvironmentAware接口的bean在该Processor内会调用EnvironmentAware接口的setEnvironment方法,<br>并把spring容器内部的ConfigurableEnvironment传递进去<br>
忽略几个接口实现类中存在依赖外部的bean属性注入
设置几个有依赖时的默认注入对象,比如,当外部类要自动注入BeanFactory时,会注入这里设置的BeanFactory(存放在一个map中),<br>这也是为什么可以注入依赖BeanFactory的原因。<br>
添加bean后置处理器:ApplicationListenerDetector,用于将实现了ApplicationListener接口的内部bean注册监听
注册几个默认的系统环境的bean
postProcessBeanFactory(beanFactory);<br>这里是提供给子类的扩展点,具体的子类可以在这步的时候添加一些特殊的 BeanFactoryPostProcessor 的实现类或做点什么事,当前例子该方法没有实现<br>
invokeBeanFactoryPostProcessors(beanFactory);<br>调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法,<br><b><font color="#e74f4c">采用注解方式时,在这里,会扫描注解将类解析成bean定义放到map中</font></b><br>
获取容器中BeanFactory后置处理器集合列表(该集合内目前还没有任何的后置处理器)
先处理BeanDefinitionRegistryPostProcessors实现类
首先从bean定义注册表获取并调用实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessors的<br>postProcessBeanDefinitionRegistry方法。会通过beanFactory.getBean先获取到bean实例(没有就创建),然后调实例的方法<br><b><font color="#e74f4c">(ConfigurationClassPostProcessor)</font></b><br>
这一步是一个关键步骤,因为ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法会进行注解扫描,<br>处理@Configuration/@Component等注解,扫描、注册包下的类,处理@Import/@ImportResource/@Bean等,<br>下面再从bean定义注册表获取就会获取到扫描到的bean定义<br>
接着从bean定义注册表获取并调用实现了Ordered接口的BeanDefinitionRegistryPostProcessors。<br>会通过beanFactory.getBean先获取到bean实例(没有就创建),然后调实例的方法<br>
然后从bean定义注册表获取并调用其它的BeanDefinitionRegistryPostProcessors(没有实现PriorityOrdered和Ordered接口)。<br>会通过beanFactory.getBean先获取到bean实例(没有就创建),然后调实例的方法<br>
最后调用上面那些的postProcessBeanFactory方法<b><font color="#e74f4c">(这里还没有调到自定义用注解标注的普通BeanFactoryPostProcessor(目前还是bd))</font></b>
后面再处理BeanFactoryPostProcessor实现类
首先创建并调用实现了PriorityOrdered接口的BeanFactoryPostProcessors的postProcessBeanFactory方法
接着创建并调用实现了Ordered接口的BeanFactoryPostProcessors的postProcessBeanFactory方法
最后创建并调用其他的BeanFactoryPostProcessors的postProcessBeanFactory方法
registerBeanPostProcessors(beanFactory);<br>注册bean后置处理器了,<b><font color="#e74f4c">实例化并注册所有 BeanPostProcessor bean</font></b><br>
首先对实现了PriorityOrdered接口的实例化并排序,然后注册进BeanPostProcessors缓存
接着对实现了Ordered接口的进行实例化,排序,注册进BeanPostProcessors缓存
然后,注册其它普通的BeanPostProcessors
最后将实现了MergedBeanDefinitionPostProcessor接口的全部排序一遍重新注册
重新注册一次BeanPostProcessor:ApplicationListenerDetector
initMessageSource();<br>国际化相关的,可以不用关注
initApplicationEventMulticaster();<br>创建事件监听广播器,用来发布事件用的<br>
onRefresh();<br>默认是空实现,交由子类重写。AnnotationConfigApplicationContext类没有重写。<br><b><font color="#e74f4c">springboot的自带的servlet容器就是在该方法内实现的。</font></b><br>
registerListeners();<br>注册监听器,将监听器注册进广播器,并发布早期事件<br>
finishBeanFactoryInitialization(beanFactory);<br>该方法是一个重要的方法,因为会在这里面实例化非懒加载的单例bean<br>
复制一份beanDefinitionNames出来遍历,以允许init等方法注册新的bean定义
得到合并后的beanDefinition
判断是否是FactoryBean
实例化FactoryBean,如果没有设置延迟,则再实例化里面的bean
实例化普通的bean(getBean(beanName))
doGetBean
1、将bean名称转换为真正的名称
2、从单例map中尝试获取bean,没获取到就跳到第4步准备去创建
3、从上一步获取到的对象中得到真正的bean,因为有可能是FactoryBean
4、判断是否有循环依赖,prototype不能有循环依赖,如果有则抛异常
5、检查一下这个 BeanDefinition 在容器中是否存在,如果有父容器并且BeanDefinition在当前容器不存在,则去父容器中查找
6、将bean标记为已创建(或将要创建)
7、重新获取合并bean定义并检查
8、初始化要依赖的Bean(depends-on)
<b><font color="#e74f4c">9、创建单例bean(重点)</font></b>
createBean<br>这个方法是返回一个完整的实例
doCreateBean
1、创建bean实例
2、应用后置处理器MergedBeanDefinitionPostProcessor,调用postProcessMergedBeanDefinition<br>(@Autowired注解正是通过此方法实现注入类型的预解析)
3、判断是否要提前暴露该bean
4、提前暴露该bean的ObjectFactory
<font color="#e74f4c"><b>5、进行属性填充,自动注入就是在这步完成的。</b></font>如果所依赖的属性是其它的bean,则会进行其它bean的初始化
6、处理 bean 初始化完成后的各种回调,比如后置处理,init方法等
调用Aware接口方法
<b><font color="#e74f4c">调用bean后置处理器的postProcessBeforeInitialization方法</font></b>
初始化bean,调用init方法,<font color="#000000">判断是否实现了InitializingBean接口,如果是则</font><b style="color: rgb(231, 79, 76);">调用afterPropertiesSet方法</b>
<b><font color="#e74f4c">调用bean后置处理器的postProcessAfterInitialization方法</font></b>
7、如果允许提前曝光实例,则进行循环依赖检查
8、注册用于销毁的bean
10、创建prototype实例
11、创建除sington和prototype其他scope的bean
到这里说明所有的非懒加载的 singleton beans 已经完成了初始化。<br>这里会<b><font color="#e74f4c">对所有实现了SmartInitializingSingleton接口的bean调用afterSingletonsInstantiated方法</font></b>,<br>这是spring提供的一个扩展点,在所有非懒加载单例bean都实例化后调用的
finishRefresh();<br>发布容器刷新完毕事件<br>
0 条评论
下一页