结论: 只要将 Bean对应的BeanDefinition注册到beanDefinitionMap中,就可以经历整个SpringBean 的生命周期,最终实例化进入单例池中
- 使用@Component 等注解配置完毕后,要配置组件扫描才能使注解生效
- xml配置组件扫描
<context:component-scan base-package ="com.itheima"/>
- 配置类配置组件扫描
@Configuration
@ComponentScan("com.itheima")
public class AppConfig {}
使用xml 方式配置组件扫描,而 component-scan 是一个context 命名空间下的自定义标签,所以要找到对应的命名空间处理器 NamespaceHandler 和 解析器,查看 spring-context 包下的spring.handlers文件
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
查看ContextNamespaceHandler 类
public void init() {
this.registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
}
将ComponentScanBeanDefinitionParser进行了注册,对其源码进行跟踪,最终将标注的 @Component 的类,生成对应的 BeanDefinition 进行了注册
使用配置类配置组件扫描,使用AnnotationConfigApplicationContext 容器在进行创建时,内部调用了如下代码,该工具注册了几个 Bean 后处理器:
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
其中,ConfigurationClassPostProcessor 是一个 BeanDefinitionRegistryPostProcessor,经过一系列源码调用,最终也被指定到了ClassPathBeanDefinitionScanner的doScan方法(与xml方式最终终点一致)