经过前四篇讲解,我们的ioc bean fanctory 已经生成;但是,bean fanctory 中在初始化时只 配置了部分的 ignoredDependencyInterfaces 和 部分的 beanDefinitionMap 属性 ,接下是对bean factory 的初始化进一步设置,先看prepareBeanFactory(beanFactory) 方法;该方法主要是给bean fanctory 上下设置标准上下文,还有 类加载器 和 后处理器(post-processors);
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置bean 工厂 beanClassLoader 属性
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 回调形式配置bean fanctory
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
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.
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.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
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.
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());
}
}
解析:给beanFanctory 设置类加载器,设置el 表达式解析器,设置资源编辑注册器;其中的涉及的类:
StandardBeanExpressionResolver :BeanExpressionResolver 的标准实现类,功能是 使用 Spring 的 expression 模块 解析 Spring 的 EL 表达式;
ResourceEditorRegistrar:PropertyEditorRegistrar 接口的实现类,使用 资源 编辑器 填充 一个 用来创建 bean 的 PropertyEditorRegistry;
ApplicationContextAwareProcessor:BeanPostProcessor 的实现类 ,用于 将 ApplicationContext 对象 传递给 实现了 EnviromenAware 接口,EmbeddedValueResolverAware 接口,ResourceLoaderAware 接口,ApplicationEventPublisherAware 接口, MessageSourceAware 接口 或者 ApplicationContextAware 接口 的 类 ;
ApplicationListenerDetector:BeanPostProcessor 的 子类 ,用于 检测 实现了 ApplicationListener 接口 的 bean;
LoadTimeWeaverAwareProcessor:BeanPostProcessor 的实现类 , 使用 LoadTimeWeaver 构造的类,该类也实现了 LoadTimeWeaver 接口;ApplicationContext 会使用内置 的 BeanFactory 自动注册该类,即上面的代码;
ResourcePatternResolver:子接口,与 父类不同的是 , ResourceLoader 只能解析一个 Resource ,而 ResourcePatternResolver 支持 资源文件的多匹配,即可返回 Resource 数组;
BeanFactory:访问 Spring bean 容器 的 根 接口;
ApplicationContext:为 应用 提供 配置 的 中央接口 ,当 应用程序在运行时,该接口是只读的,但是可以重新加载,如果实现支持的话;
ResourceLoader: 加载 资源的策略接口(例如 类路径下 或者 文件系统下 资源),ApplicationContext 需要提供 这个功能,通过 继承 ResourcePatternResolver 得到支持;
扩展知识 Aware : 标记 接口,表示 一个 bean 需要通过 回调形式 的 方法 被 Sping 容器中的 一个 特殊的 框架对象 通知;
EnvironmentAware:实现该 接口的类 希望得到正在运行中的 Environment 对象的 通知;即 可以实时获取 当前的 Environment 对象
EmbeddedValueResolverAware:内部定义的值的解决方案
ResourceLoaderAware:任何实现该接口的 对象 希望得到 实时的 ResourceLoader 对象的通知(通常是 ApplicationContext)
ApplicationEventPublisherAware:应用事件发布器,可以发布事件
MessageSourceAware:获得message source,这也可以获得文本信息
ApplicationContextAware:此接口中有一个setApplicationContext的方法,实现此方法便可以获取到applicationContext对象
BeanFactoryAware: 此接口中有一个setBeanFactory的方法,实现此方法便可以获取到BeanFactory对象;