Spring IOC(2)----如何注册bean定义

前面说到IOC容器在刷新之前的一些初始化工作,现在来看看在refresh()方法中,是怎样来加载注册我们自己的bean定义的。

refresh()方法中有很多功能,从注释中就可以看出来

 

我们本次重点关注invokeBeanFactoryPostProcessors(beanFactory);这个方法

该方法里面可以获取到前面初始化好的注解读取器AnnotatedBeanDefinitionReader,前面在AnnotationConfigUtils#registerAnnotationConfigProcessors方法中是往beanFactory里面注册了配置类的处理器的ConfigurationClassPostProcessor,这个时候就可以拿出来使用了,创建一个配置类解析器对象ConfigurationClassParser,来具体处理几种形式bean注入(@propertySource,@ComponentScan,@Import,@ImportResource,@bean),,最终再由ConfigurationClassBeanDefinitionReader将配置的bean定义加载到容器中ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass

1.PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors方法中判断我们的beanFactory是否是bean定义注册器,如果是就依次执行相应的bean定义处理器,进行注册bean定义,否则执行依次执行相应的beanFactory处理器。

2.容器中如果已经实例化好的BeanFactoryPostProcessor先行执行

 

 

 

 

 

当然我们进行肯定是执行的bean注册。

 2.其次从beanFactory中获取实现了PriorityOrdered接口的bean定义处理器。如果有的话立马对它进行实例化。PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors这个方法是关键,ConfigurationClassPostProcessor这个类就是实现PriorityOrdered接口的处理器

 

 

 

 

 

 

3.现在就看ConfigurationClassPostProcessor类中怎么处理来bean定义的注册了。ConfigurationClassPostProcessor#processConfigBeanDefinitions方法拿到目前已有的bean定义,判断哪些是处理过了的,哪些是还需要处理。如果没有就返回了。实际上最终会拿到我们自己的配置类我们标注了@Configuration注解的类。

 

4.ConfigurationClassParser#parse方法到doProcessConfigurationClass真正解析我们的配置类,解析@PropertySource,@ComponentScan,@Import,@ImportResource,@Bean这些注解,扫描注解就包含了扫描到@Component,@service,@Controller这些注解

 

 

 

 

 

5.扫描的时候会将将配置信息放一个扫描对象中去,然后执行ClassPathBeanDefinitionScanner的parse方法到doScan方法对包进行扫描,也就是会将@Component,@service,@Controller这些注解的类扫描注册。完了这里还有重复检查操作,万一这些注解类上面还有其他配置,再次进行解析。

 

 

 

 

 

 

6.然后解析@Import和@Bean注解不过这两个注解导入的类,在这里并不会立马注册到beanFactory中

 

 

 7.ConfigurationClassBeanDefinitionReader#loadBeanDefinitions到loadBeanDefinitionsForConfigurationClass方法里面才会去将@Import和@bean注解导入类加入bean定义中。至此PriorityOrdered类型的bean定义解析器(ConfigurationClassPostProcessor)就执行完毕,到这里我们自己所配置的那些类的定义也注册到了容器中了。

 

 8.接下来是实现了Ordered接口的bean定义解析器的执行,一般来说是没有的,如果我们自己有配置实现这个类型的bean定义解析器,就会在这个阶段立马实例化然后执行它的postProcessBeanDefinitionRegistry方法。

 

 

 

 

 9.在接着就是没有执行过的其他类型bean定义解析器也会被立马实例化执行。比如我们自己实现BeanDefinitionRegistryPostProcessor这个接口的bean定义处理器就是在这个地方执行了。这个时候第三方包中的类的定义都已经注册好了,这个时候我们想要新加自己的bean定义进去,或者替换掉第三方类,就可以在这里将第三方的删掉,把我们自己的类的bean定义注册进去。

 

 

 

 

 比如这个就是将以前包里面的实现类换掉,替换成自己新的实现。这个是因为公司的以前的公共包里面封装了很多公共的东西。然后新的服务要求时间类型用java8.然而公司以前的那个包里面用的不是java8的时间。如果不要用以前封装的包,很多功能全部都需要重新写。

因此就通过这个方式,把原来包中的实现换成了新的。

 

至此整个bean定义的注册就完成了。

10。最后就是beanFactory的处理器,也是按照先执行容器已经实例化好的,然后是实现PriorityOrderedOrdered接口的,最后是其他的

这里也可以实现自己的bean工厂后置处理器BeanFactoryPostProcessor,不过这里不能添加或者删除了,只能修改bean定义的属性了。比如设置某个bean为懒加载

 

 

 

 

 至此整个bean定义的注册流程就结束了,invokeBeanFactoryPostProcessors这个方法核心流程也分析完毕了。

 

关键入口流程图如下:

 

posted @ 2019-10-07 18:56  白露非霜  阅读(1254)  评论(0编辑  收藏  举报
访问量