知道容器新建了BeanFactory,并且解析配置文件中的 bean 为 BeanDefination 缓存起来了,接下来学习AbstractApplicationContext # prepareBeanFactory(beanFactory) 都干了啥!
其主要的工作就是完善beanFactory的能力。
配置类加载器,EL表达式解析器,属性解析器。
// Tell the internal bean factory to use the context's class loader etc.
// 设置类加载器,就是当前context的类加载器,用于加载bean
beanFactory.setBeanClassLoader(getClassLoader());
// 设置EL表达式解析器,为了可以使用类似${bean.xxx}的表达式
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性解析器,可以通过扩展增加自定义的属性解析器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
增加扩展对象
/**
* 将当前的ApplicationContext 交给 ApplicationContextAwareProcessor类处理。
* beanFactory中使用一个集合存放这些扩展类。
* private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
*/
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 因为 ApplicationContextAwareProcessor 处理了以下接口,所以这里就直接忽略掉
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
注册特殊的 bean,他们使用指定的对象注入。
/**
* registerResolvableDependency 表示该类型使用指定的对象注入
* BeanFactory.class 注入 beanFactory 对象
* ResourceLoader.class、ApplicationEventPublisher.class、ApplicationContext.class 注入this
*/
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
注册监听器
// 注册处理监听器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
支持 Aspectj
/**
* 检查容器中是否包含名称为 loadTimeWeaver 的bean,其为了增加支持 Aspectj。
* AspectJ 采用编译期织入(LTW:Load Time Weaver)、类加载期织入两种方式进行切面的织入。
* LTW,通过特殊的类加载器来代理JVM默认的类加载器实现。
*/
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()));
}
注册环境相关的 bean
// 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());
}