启动Spring应用
只需简单的几行代码便可声明、创建一个Spring应用容器。
1  | AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(BasicConfig.class);  | 
创建容器
在进入到 new AnnotationConfigApplicationContext() 方法后,进行对容器的声明和创建。其中会先对给定的配置文件类进行校验和注册。调用过程草图如下所示(仅参考):

可以看到基本的调用顺序,下面根据图中所示,针对调用的方法进行源码的分析。
创建 AnnotationConfigApplicationContext
创建对象

因为在使用 new AnnotationConfigApplicationContext() 创建对象时会默认调用父类的无参构造函数,也就是默认调用 super() 方法。根据图中的类继承结构,看看在父类中都定义了哪些对象,并且这些对象的作用是什么。
- 首先在AnnotationConfigApplicationContext继承了GenericApplicationContext,在构造方法内创建了beanFactory
 
1  | public GenericApplicationContext() {  | 
- GenericApplicationContext 继承 AbstractApplicationContext,在构造方法内定义了resourcePatternResolver
 
1  | public AbstractApplicationContext() {  | 
- AbstractApplicationContext 继承了 DefaultResourceLoader,在构造方法内定义了 classLoader
 
1  | public DefaultResourceLoader() {  | 
通过上述代码和分析可以发现调用 new AnnotationConfigApplicationContext() 时会通过调用父类的无参构造函数鬼定义如下内容:
- 设置 
beanFactory为DefaultListableBeanFactory类型 - 设置 
resourcePatternResolver为PathMatchingResourcePatternResolver类型 - 设置 
classLoader为默认的线程环境的classLoader 
1  | public AnnotationConfigApplicationContext(Class<?>... componentClasses) {  | 
 调用构造函数时可以发现他会先初始化一个 reader 和一个 sacnner。 分别的作用为 :
AnnotatedBeanDefinitionReader用于以编程方式注册Bean类,这些Bean主要指的时一些PostProcessorClassPathBeanDefinitionScanner一个可在类路径上搜索候选bean的bean定义扫描器。
AnnotatedBeanDefinitionReader
用于以编程方式注册Bean类,这些Bean主要指的是一些PostProcessor。
1  | public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {  | 
通过代码总结一下,在new AnnotatedBeanDefinitionReader 的时候,都做了些什么;
- 将 AnnotationConfigApplicationContext 作为 register 设置到AnnotatedBeanDefinitionReader中
 - 设置 ConditionEvaluator 用作与对 @Condition 的解析
 - 在给定的register也就是AnnotationConfigApplicationContext中注册所有相关的注解后置处理器。
- 添加BeanFactory的相关属性,DependencyComparator和AutowireCandidateResolver
 - 注册ConfigurationClassPostProcessor 用于解析
@Configuration注解标注的类 - 注册AutowiredAnnotationBeanPostProcessor用于解析
@Autowire注解标注的类 - 注册 CommonAnnotationBeanPostProcessor 用于解析 
JSR-250相关注解,如Resource、EJB、WebServiceRef - 注册PersistenceAnnotationBeanPostProcessor用于解析
JPA相关注解 - 注册EventListenerMethodProcessor、DefaultEventListenerFactory用于事件监听
 
 
ClassPathBeanDefinitionScanner
一个可在类路径上搜索候选bean的bean定义扫描器。
1  | public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,  | 
其中最重要的是使用ClassPathScanningCandidateComponentProvider类中 registerDefaultFilters 方法注册默认的过滤器,主要包含三部分
- 为@Component,同时保证了Repository、Service、Controller这四个注解添加过滤器
 - 为 ManagedBean(JSR-250) 添加过滤器
 - 为 Named(JSR-330) 添加过滤器
 
register 注册给定配置类
1  | 
  | 
registerBean
在上一步的 registerBean 中调用了已经创建好的 AnnotatedBeanDefinitionReader 的 registerBean方法:
1  | public void register(Class<?>... componentClasses) {  | 
对每一个 class 循环调用 doRegisterBean 方法进行 对 BeanClass 的注册操作。
doRegisterBean
在doRegisterBean中分为如下几步进行操作:
- 声明 
BeanDefinition为AnnotatedGenericBeanDefinition。 - 通过 
conditionEvaluator.shouldSkip()方法通过对 @Conditional 注解来判断是否跳过注册 - 通过 
scopeMetadataResolver.resolveScopeMetadata来获取作用域,然后再放到 BeanDefinition 中。 - 通过 
beanNameGenerator.generateBeanName来设置Bean在容器中的名称。 - 通过 
processCommonDefinitionAnnotations设置Bean的基本属性 - 最后通过 调用
registerBeanDefinition对包装好的 BeanDefinitionHolder 进行最后的注册操作。 
1  | private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,  | 
registerBeanDefinition
1  | public static void registerBeanDefinition(  | 
之后会调用 DefaultListableBeanFactory 中的 registBeanDefinition 方法对Bean进行注册。
实际的注册过程就是将Bean的名称作为key,Bean的BeanDefinition作为value存储在一个全局的beanDefinitionMap中。
1  | synchronized (this.beanDefinitionMap) {  | 
至此,Spring容器的创建,和对配置文件的注册就完成了。