达式; Bean 初始化完成后填充属性时会用到
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 设置属性注册解析器,主要用来解析 Bean 中的各种属性类型,如 String、int 等
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加一个后置处理器:ApplicationContextAwareProcessor。
// 该后置处理器用于向实现了 Aware 系列接口的 bean 设置相应属性。
// (后置处理器和 Aware 接口也是比较核心的概念,后面会有文章详细讨论)
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 以下接口,在自动注入时会被忽略,其都是 Aware 系列接口
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 需自动注入时,指定其注入的类型 。
// 如:注入 BeanFactory 时,注入的类型对象为 ConfigurableListableBeanFactory 。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 添加 ApplicationListenerDetector 后置处理器。
// 该后置处理器用来检测那些实现了 ApplicationListener 接口的 bean,并将其添加到应用上下文的事件广播器上。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 判断容器中是否存在 loadTimeWeaver Bean,如果存在则上下文使用临时的 ClassLoader 进行类型匹配。
// 集成 AspectJ 时会用到 loadTimeWeaver 对象。
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册和环境相关的 Bean,如 environment、systemProperties、systemEnvironment
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());
}
}
在 prepareBeanFactory 方法中,主要对 BeanFactory 添加了一系列属性项,如添加忽略自动注入的接口、添加 BeanPostProcessor 后置处理器、手动注册部分特殊的 Bean及环境相关的 Bean 。
第四步:postProcessBeanFactory
postProcessBeanFactory 方法是上下文准备的最后一步,主要用来注册 Web 请求相关的处理器、Bean及配置。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
...
postProcessBeanFactory(beanFactory);
...
}
}
该方法也是由子类进行扩展,实现该方法的子类有:
前面也说过,当前是 Servlet Web 应用,所以创建的 ApplicationContext 上下文是 AnnotationConfigServletWebServerApplicationContext,执行该类的 postProcessBeanFactory 方法。
public class AnnotationConfigServletWebServerApplicationContext
extends ServletWebServerApplicationContext implements AnnotationConfigRegistry {
private final AnnotatedBeanDefinitionReader reader;
private final ClassPathBeanDefinitionScanner scanner;
private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();
private String[] basePackages;
...
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 先执行父类 ServletWebServerApplicationContext 的 postProcessBeanFactory 方法。
// 跳转到 1 查看父类实现
super.postProcessBeanFactory(beanFactory);
// basePackages 存储的是类路径。先判断是否为 null,不为 null 则通过 ClassPathBeanDefinitionScanner 的 scan 方法
// 扫描该路径下符合条件的 Class,并将 Class 信息包装成 BeanDefinition 注册到容器中,
// 当然,这里没有指定扫描路径,所以不会进入这个 if。
// (BeanDefinition 概念会在后面章节详细讨论)
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
// annotatedClasses 存储的 Class 集合。先判断该集合是否为空,不为空则通过
// AnnotatedBeanDefinitionReader 的 register 方法将 Class 信息包装成 BeanDefinition 注册到容器中,
// 这里同样没有设置 Class 集合内容,所以不会进入这个 if。
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}
}
1、
public class ServletWebServerApplicationContext extends GenericWebApplicationContext
implements ConfigurableWebServerApplicationContext {
...
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 添加 BeanPostProcessor 后置处理器:WebApplicationContextServletContextAwareProcessor,
// 该后置处理器主要是从 ConfigurableWebApplicationContext 上下文中获取 ServletContext 和 ServletConfig 对象
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
// 添加一个 忽略自动注入的接口
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
...
}
postProcessBeanFactory 方法执行的操作和前面类似,也是添加了后置处理器和忽略自动注入的接口。
总结
ApplicationContext 上下文准备工作基本结束,主要还是在 BeanFactory 中添加一系列后置处理器、注册特殊的 Bean 及设置忽略自动注入的接口。其中还提到了 Spring 容器的三个核心部分:Aware 系列接口、BeanPostProcessor 后置处理器、BeanDefinition ,这部分在后面的文章会逐步讨论。接下来将对 Spring 容器的核心功能展开讨论。