一、寻找外围办法
// == 入口
public static void main(String[] args) {SpringApplication.run(SpringRunner.class, args);
}
// == 调用链
org.springframework.boot.SpringApplication#run(java.lang.Class<?>, java.lang.String...)
org.springframework.boot.SpringApplication#run(java.lang.Class<?>[], java.lang.String[])
org.springframework.boot.SpringApplication#run(java.lang.String...)
org.springframework.boot.SpringApplication#refreshContext
org.springframework.boot.SpringApplication#refresh
记住 refresh 办法
,它 十分重要
察看它的外部实现:
// ##### IOC 容器初始化 #####
// 告知子类要初始化 BeanFactory
// BeanDefinition 信息的读取是在子类的 refreshBeanFactory()办法里实现的
ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
// 筹备 bean 工厂以在此上下文中应用。this.prepareBeanFactory(beanFactory);
// ##### 驰名的九大办法 #####
try {
// 设置 beanFactory 的后置解决
postProcessBeanFactory(beanFactory);
// 调用 beanFactory 的后置解决,如 springboot 主动拆卸获取配置的 Entity
invokeBeanFactoryPostProcessors(beanFactory);
// 注册 beanFactory 的后置解决
registerBeanPostProcessors(beanFactory);
// 初始化上下文的音讯
initMessageSource();
// 初始化高低的事件
initApplicationEventMulticaster();
// 初始化一些非凡的 bean
onRefresh();
// 查看一些监听的 bean 并注册到容器中
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons,spring bean 对象初始化在这里
finishBeanFactoryInitialization(beanFactory);
// 公布容器事件,完结 Refresh 过程
finishRefresh();
二、注册和扫描
本节深入分析构建 BeanFactory 的过程。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// == 调用链
org.springframework.context.support.AbstractApplicationContext#obtainFreshBeanFactory
org.springframework.context.support.AbstractRefreshableApplicationContext#refreshBeanFactory
// -- 剖析注解形式注入
org.springframework.web.context.support.AnnotationConfigWebApplicationContext#loadBeanDefinitions
1. 向容器注册对象信息
注入的实质就是向容器 (也有叫上下文的,就是 Context 的直译)——本质就是一个 Map 注册类的形容信息。
用代码形容就是:beanDefinitionMap.put(BeanDefinition)
看看具体实现:
// == 注册逻辑
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory);
if (!this.annotatedClasses.isEmpty()) {reader.register(this.annotatedClasses.toArray(new Class<?>[this.annotatedClasses.size()]));
}
}
// == 调用链
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#register
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#registerBean(java.lang.Class<?>)
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
这个办法值得细说一下:
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
//## 被注解润饰的对象,会被封装成 BeanDefinition 构造
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
// 为注解 Bean 定义生成 Bean 名称
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
// BeanDefinition 再次封装
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
// ## 注入
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
// == 调用链
org.springframework.beans.factory.support.BeanDefinitionReaderUtils#registerBeanDefinition
// -- 后面创立的工厂是 DefaultListableBeanFactory
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition
最终的注入逻辑:
// 存储注册信息的 BeanDefinition
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
// ## 注入的实质
this.beanDefinitionMap.put(beanName, beanDefinition);
}
2. 扫描指定 package 的配置信息
无它,只为 扩充扫描范畴 。
默认只注入 SpringRunner(Starter 类)的子包
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {
// 为容器设置类门路 Bean 定义扫描器
ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory);
if (!this.basePackages.isEmpty()) {scanner.scan(this.basePackages.toArray(new String[this.basePackages.size()]));
}
}
// == 调用链
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#scan
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
// 遍历扫描所有给定的包
for (String basePackage : basePackages) {
// ## 同样执行注入流程
registerBeanDefinition(definitionHolder, this.registry);
}
}
未完待续(懒癌发生……)