BeanFactory注册Bean测试
上面的代码就是自己创建一个BeanFactory进行Bean的注册。
可以看到,结果却不太理想,只是把Config类注入了,却没有把里面的Bean1到Bean4注入,这是为什么?
引入PostProcessor后处理器类
我们平时开发的时候只要使用了@Configuration注解,配置类里面的bean就会自动注入,其实都是BeanFactory后处理器的功劳,是后处理器对这些需要注入的Bean进行了处理解析。它的作用就是动态的注册一些BeanDefinition,并将其添加到容器中。作用时机在容器实例化、配置和初始化Bean之前,可以对BeanFactory进行修改和扩展,以适应特定的需求。这样可以在Bean实例化之前对BeanDefinition进行更改,包括修改属性值、添加属性等。
简单介绍一下这几个后处理器
- org.springframework.context.annotation.internalConfigurationAnnotationProcessor//解析Configuration注解处理器,可以把里面的类似@Bean注解等解析
- org.springframework.context.annotation.internalAutowiredAnnotationProcessor//解析Autowired注解处理器
- org.springframework.context.annotation.internalCommonAnnotationProcessor//解析Common和Resource注解处理器
- org.springframework.context.event.internalEventListenerProcessor//解析EventListener事件监听处理器
- org.springframework.context.event.internalEventListenerFactory//EventListener事件监听工厂
BeanFactoryPostProcessor的调用
但是我们也发现了,即使是加入了这些Bean工厂后处理器也没用把之前的Bean1到Bean4注入容器啊?
实际上是因为这些后处理器虽然加入了容器,但是没有进行调用
测试依赖注入
引入BeanPostProcessor后处理器类
因为Bean2属性上面加了@Autowired注解,没有注入成功则说明肯定是注解没生效。可能你会有这样的疑问:上面不是已经注入了BeanFactory后处理器和调用了后处理器吗?而且刚刚注入常用的后处理器中不也有@Autowired注解解析器吗,为什么没生效?
其实这是一个很容易混淆的地方:BeanFactoryPostProcesser和BeanPostProcessor是不一样的,一个是Bean工厂后处理器,一个是Bean后处理器,两者作用时机不一样
- BeanFactoryPostProcessor,可以在spring的bean创建之前,修改bean的定义属性。也就是说,Spring允许BeanFactoryPostProcessor在容器实例化任何其它bean之前读取配置元数据,并可以根据需要进行修改
- BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。
我们上面使用的internalConfigurationAnnotationProcessor显然是一个Bean工厂后处理器,那么在作用@Configuration这些配置注解时是会生效的。但是我们现在需要的是对@Autowired注解进行处理,而这个注解的发生时机则在Bean的依赖注入阶段,则需要的是Bean后处理器。那么显然我们刚刚说到的internalAutowiredAnnotationProcessor是一个Bean后处理器,但是注意这里说这两个后处理器在Spring中不是真的就叫这个名字,这些后处理器并不是一个特定的类或接口,而是指 Spring Framework 中用于处理配置类注解的内部处理器的概括性术语。
总结
这篇文章主要是想大家能理解好BeanFactory后处理器和Bean后处理器的差别和调用时机
其次,其实BeanFactory还有很多常用的实现类,这里就不带大家一一去看了,我简单介绍两个重要的容器
- DefaultListableBeanFactory:一个非常重要的类,它包含了IOC容器所应该具备的重要功能,是容器完整功能的一个基本实现
- ConfigurableApplicationContext:我们的spring.run方法返回的就是这个容器,主要是refresh方法,是这个高级容器中的核心方法,包括了高级容器初始化的主要流程
有机会的话我会再给大家讲讲这两个容器。