本文描述的IOC基于注解的方式启动容器
配置资源的读取加载(register()方法)
Spring容器初始化的时候关键就是refresh()方法,但在执行refresh方法之前,还要进行容器的配置资源的读取和加载,所以就会执行register()方法。
通过注解的方式启动容器:
AnnotationConfigApplicationContext applicationContext =
new AnnotationConfigApplicationContext(JavaConfig.class);
然后,在DefaultListableBeanFactory类中的registerBeanDefinition()
方法上打上断点,因为不管如何调用,最终都要将BeanDefinition注册进BeanFactorty(DefaultListableBeanFactory)中
从调试中可以看到,Spring基本的beanDefinition会首先注册进DefaultListableBeanFactory中,从左边的调用栈可以看到,这些beanDefinition在AnnotationConfigApplicationContext的构造方法的this()
方法中被调用(构造方法如下👇)
//最常用的构造函数,将涉及到的配置类传递给该构造函数,以实现将相应配置类中的Bean自动注册到容器中
public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
//调用父类构造方法
this();
//把传入的Class进行注册,Class既可以有@Configuration注解也可以没有@Configuration注解
//如何注册委托给了org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register方法
//包装传入的Class 生成 BeanDefinition,注册到BeanDefinitionRegistry
register(annotatedClasses);
refresh();
}
当进行下一步的调试可以看到,当beanName是我们在AnnotationConfigApplicationContext的构造方法中传入的beanName时,说明Spring基本的配置BeanDefinition已经注册完毕,开始注册我们自定义的bean,这时候通过调用栈可以看到,执行的是register()
方法。
再往后,就是注册自定义的普通的bean的BeanDefinition,就是被@Bean、@Component等标记的bean,执行的是refresh()
方法
小结
在容器refresh之前,首先会把spring基本的beanDefinition注册进容器中,其次是由构造方法传入的bean(一般都是被@Configuration标记的类),其他的bean则在refresh中被创建,这个在分析refresh的时候再说。