Spring 源码之核心加载方法(3) beanFactory 的准备工作

3. prepareBeanFactory

定位: org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 告知内部的bean工厂,使用上下文的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
// 设置 bean 表达式语言解析器
// 默认 StandardBeanExpressionResolver 成员变量 expressionParser 是 SpelExpressionParser (即 spring el表达式) 类型
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加 beanFactory 默认的 PropertyEditorRegistrar,主要是对 bean 的属性等设置管理的一个工具类
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// Configure the bean factory with context callbacks.
// 添加 Bean 后置处理器
// 初始化bean之前处理 Aware 接口, EnvironmentAware、EmbeddedValueResolverAware、ResourceLoaderAware、ApplicationEventPublisherAware、MessageSourceAware 和 ApplicationContextAware
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置要忽略自动装配的接口
// 为什么此处要对这些接口进行忽略,
// 原因:这些接口的实现是由容器通过set方法进行注入的,所以在使用 autowire 进行注入的时候需要将这些接口进行忽略
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
// 设置几个自动装配的特殊规则,当在进行ioc初始化的如果有多个实现,那么就使用指定的对象进行注入
// 在 Spring 自动装配的时候如果一个接口有多个实现类,使用 registerResolvableDependency 指定接口的实例
// 类似作用的有使用 @Primary
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// Register early post-processor for detecting inner beans as ApplicationListeners.
// 添加 Bean 后置处理器
// 初始化 bean 之后处理事件监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 增加对 AspectJ 的支持,在 java 中织入分为三种方式,分为编译器织入,类加载器织入,运行期织入,编译器织入是指在java编译器,采用特殊的编译器,将切面织入到java类中,
// 而类加载期织入则指通过特殊的类加载器,在类字节码加载到JVM时,织入切面,运行期织入则是采用 cglib 和 jdk 进行切面的织入
// Aspectj 提供了两种织入方式,第一种是通过特殊编译器,在编译器,将 Aspectj 语言编写的切面类织入到 java 类中,第二种是类加载期织入,就是下面的l oad time weaving
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

// Register default environment beans.
// 注册默认的系统环境 bean 到一级缓存中
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
// 环境变量
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
// 系统属性
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
// 系统环境变量
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}

ResourceEditorRegistrar