本文已参与「新人创作礼」活动,一起开启掘金创作之路。
6.忽略 bean 信息
进入configureIgnoreBeanInfo()方法如下:
就是获取了 spring.beaninfo.ignore 参数, 如果没有该参数, 默认设置为 true, 具体作用未知.
7.打印 banner 信息
这部分源码参考: SpringBoot 自定义 Banner
8.创建应用程序的上下文 context
进入createApplicationContext()方法:方法内部根据应用类型, 然后使用反射创建对应的容器 context 类型.
创建的 Servlet Web 容器为:
查看 org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext的继承关系如下:
通过 debug 也能看到, 在创建 AnnotationConfigServletWebServerApplicationContext 时, 会依次向上调用其父类的构造方法, -> ServletWebServerApplicationContext -> GenericWebApplicationContext -> GenericApplicationContext -> AbstractApplicationContext.
应用上下文可以理解成 IoC 容器的高级表现形式, 应用上下文确实是在IoC容器的基础上丰富了一些高级功能. 应用上下文对 IoC 容器是持有的关系. 他的一个属性 beanFactory 就是 IoC 容器.
而 GenericApplicationContext 对象有个 beanFactory 属性如下:
没错, DefaultListableBeanFactory就是 IoC 容器真实面目了, beanDefinitionMap 就是它的属性. 在后面的 refresh() 方法分析中, DefaultListableBeanFactory 是无处不在的存在感.
在 AnnotationConfigServletWebServerApplicationContext 的无参构造方法中, 调用了如下两个方法:
1.AnnotatedBeanDefinitionReader
从类名上看, 是把用注解方式定义的 Bean 读取解析出来.
进入AnnotatedBeanDefinitionReader的构造方法如下:
在调用构造方法前, AnnotatedBeanDefinitionReader 类中有两个属性, 还需要进行初始化, 如下:
从类的名字就能看出:
AnnotationBeanNameGenerator负责生成 Bean 的名字 gotoAnnotationScopeMetadataResolver负责解析 @Scope 注解, 如果Bean上有.
创建了这两个对象后, 然后创建ConditionEvaluator对象, ConditionEvaluator 是@Conditional注解的条件评估器, 评估是否满足条件.
方法内部, 又创建了ConditionContextImpl对象, 然后推断了一些参数.
然后调用了AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);该方法会将一些 bean 的自动处理器加入到 AnnotationConfigApplicationContext 下的 BeanFactory 中.
比如:
- AutowiredAnnotationBeanPostProcessor 处理 @Autowired 注解和 @Value 注解
- RequiredAnnotationBeanPostProcessor 处理 @Required 注解
- PersistenceAnnotationBeanPostProcessor 是对 JPA 注解的支持
- CommonAnnotationBeanPostProcessor 对 JSR-250 规范注解@Resource / @PostConstruct / @PreDestroy 等的支持
- EventListenerMethodProcessor 对 @EventListener 的支持
\
2.ClassPathBeanDefinitionScanner
从类名上看, 是把 classpath 下的 bean 扫描出来, 也就是一个扫描器.
进入其构造方法:
2.1.注册默认的扫描过滤规则
useDefaultFilters 默认为 true, 所以会执行registerDefaultFilters()方法, 该方法会注册几个默认的 AnnotationTypeFilter:
- 对 @Component 及子注解的
- 对 @ManagedBean 注解的
- 对 @Named 注解的
这些过滤规则存放在includeFilters属性中, 该属性是在其父类ClassPathScanningCandidateComponentProvider中定义的.
类 ClassPathBeanDefinitionScanner 的继承结构如下:
过滤规则属性:
此处只是添加了过滤规则, 并不会进行 bean 的扫描.
\
执行到这里时, context 的部分属性已经填充好了:
9.实例化异常报告器
又见到熟悉的 getSpringFactoriesInstances() 方法了, 这里是获取 key = SpringBootExceptionReporter 的类并实例化.
异常报告器的作用:捕捉 SpringBoot 项目启动时发生的异常. 只会捕获启动过程抛出的异常, 如果是在启动完成后, 在用户请求时报错, 异常报告器不会捕获请求中出现的异常.
默认的异常报告器为:
启动过程: